From 1aeeb1ee9f863f70c6ec443b40f74c60d7483607 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Fri, 7 Jan 2022 19:54:09 +0000 Subject: [PATCH] Remove code still using old "length_sessionX" SessionForm fields. Commit ready for merge. - Legacy-Id: 19826 --- ietf/secr/sreq/templatetags/ams_filters.py | 5 +- ietf/secr/sreq/tests.py | 133 +++++++++++++++++- ietf/secr/sreq/views.py | 31 +++- ietf/secr/templates/includes/session_info.txt | 2 +- 4 files changed, 156 insertions(+), 15 deletions(-) diff --git a/ietf/secr/sreq/templatetags/ams_filters.py b/ietf/secr/sreq/templatetags/ams_filters.py index 47109a081..125acdeda 100644 --- a/ietf/secr/sreq/templatetags/ams_filters.py +++ b/ietf/secr/sreq/templatetags/ams_filters.py @@ -33,7 +33,10 @@ def display_duration(value): 3600: '1 Hour', 5400: '1.5 Hours', 7200: '2 Hours', - 9000: '2.5 Hours'} + 9000: '2.5 Hours', + 10800: '3 Hours', + 12600: '3.5 Hours', + 14400: '4 Hours'} if value in map: return map[value] else: diff --git a/ietf/secr/sreq/tests.py b/ietf/secr/sreq/tests.py index c1907c680..f01721358 100644 --- a/ietf/secr/sreq/tests.py +++ b/ietf/secr/sreq/tests.py @@ -95,6 +95,7 @@ class SessionRequestTestCase(TestCase): attendees = 10 comments = 'need lights' mars_sessions = meeting.session_set.filter(group__acronym='mars') + empty_outbox() post_data = {'num_session':'2', 'attendees': attendees, 'constraint_chair_conflict':iabprog.acronym, @@ -156,11 +157,16 @@ class SessionRequestTestCase(TestCase): self.assertContains(r, group2.acronym) self.assertContains(r, 'Second session with: {} {}'.format(group3.acronym, group4.acronym)) + # check that a notification was sent + self.assertEqual(len(outbox), 1) + notification_payload = get_payload_text(outbox[0]) + self.assertIn('1 Hour, 1 Hour', notification_payload) + self.assertNotIn('1 Hour, 1 Hour, 1 Hour', notification_payload) + # Edit again, changing the joint sessions and clearing some fields. The behaviour of # edit is different depending on whether previous joint sessions were recorded. + empty_outbox() post_data = {'num_session':'2', - 'length_session1':'3600', - 'length_session2':'3600', 'attendees':attendees, 'constraint_chair_conflict':'', 'comments':'need lights', @@ -206,6 +212,12 @@ class SessionRequestTestCase(TestCase): self.assertEqual(list(sessions[0].joint_with_groups.all()), [group2]) self.assertFalse(sessions[1].joint_with_groups.count()) + # check that a notification was sent + self.assertEqual(len(outbox), 1) + notification_payload = get_payload_text(outbox[0]) + self.assertIn('1 Hour, 1 Hour', notification_payload) + self.assertNotIn('1 Hour, 1 Hour, 1 Hour', notification_payload) + # Check whether the updated data is visible on the view page r = self.client.get(redirect_url) self.assertContains(r, 'First session with: {}'.format(group2.acronym)) @@ -579,7 +591,7 @@ class SubmitRequestCase(TestCase): sessions = Session.objects.filter(meeting=meeting,group=group) self.assertEqual(len(sessions), 2) session = sessions[0] - + self.assertEqual(session.resources.count(),1) self.assertEqual(session.people_constraints.count(),1) self.assertEqual(session.constraints().get(name='time_relation').time_relation, 'subsequent-days') @@ -597,6 +609,115 @@ class SubmitRequestCase(TestCase): self.assertTrue(ad.ascii_name() in notification_payload) self.assertIn(ConstraintName.objects.get(slug='chair_conflict').name, notification_payload) self.assertIn(group.acronym, notification_payload) + self.assertIn('1 Hour, 1 Hour', notification_payload) + self.assertNotIn('1 Hour, 1 Hour, 1 Hour', notification_payload) + self.assertNotIn('The third session requires your approval', notification_payload) + + def test_request_notification_third_session(self): + meeting = MeetingFactory(type_id='ietf', date=datetime.date.today()) + ad = Person.objects.get(user__username='ad') + area = GroupFactory(type_id='area') + RoleFactory(name_id='ad', person=ad, group=area) + group = GroupFactory(acronym='ames', parent=area) + group2 = GroupFactory(acronym='ames2', parent=area) + group3 = GroupFactory(acronym='ames2', parent=area) + group4 = GroupFactory(acronym='ames3', parent=area) + RoleFactory(name_id='chair', group=group, person__user__username='ameschairman') + resource = ResourceAssociation.objects.create(name_id='project') + # Bit of a test data hack - the fixture now has no used resources to pick from + resource.name.used=True + resource.name.save() + + url = reverse('ietf.secr.sreq.views.new',kwargs={'acronym':group.acronym}) + confirm_url = reverse('ietf.secr.sreq.views.confirm',kwargs={'acronym':group.acronym}) + len_before = len(outbox) + attendees = '10' + post_data = {'num_session':'2', + 'third_session': 'true', + 'attendees':attendees, + 'bethere':str(ad.pk), + 'constraint_chair_conflict':group4.acronym, + 'comments':'', + 'resources': resource.pk, + 'session_time_relation': 'subsequent-days', + 'adjacent_with_wg': group2.acronym, + 'joint_with_groups': group3.acronym, + 'joint_for_session': '2', + 'timeranges': ['thursday-afternoon-early', 'thursday-afternoon-late'], + 'session_set-TOTAL_FORMS': '3', + 'session_set-INITIAL_FORMS': '0', + 'session_set-MIN_NUM_FORMS': '1', + 'session_set-MAX_NUM_FORMS': '3', + # no 'session_set-0-id' for new session + 'session_set-0-name': '', + 'session_set-0-short': '', + 'session_set-0-purpose': 'regular', + 'session_set-0-type': 'regular', + 'session_set-0-requested_duration': '3600', + 'session_set-0-on_agenda': True, + 'session_set-0-remote_instructions': '', + 'session_set-0-attendees': attendees, + 'session_set-0-comments': '', + 'session_set-0-DELETE': '', + # no 'session_set-1-id' for new session + 'session_set-1-name': '', + 'session_set-1-short': '', + 'session_set-1-purpose': 'regular', + 'session_set-1-type': 'regular', + 'session_set-1-requested_duration': '3600', + 'session_set-1-on_agenda': True, + 'session_set-1-remote_instructions': '', + 'session_set-1-attendees': attendees, + 'session_set-1-comments': '', + 'session_set-1-DELETE': '', + # no 'session_set-2-id' for new session + 'session_set-2-name': '', + 'session_set-2-short': '', + 'session_set-2-purpose': 'regular', + 'session_set-2-type': 'regular', + 'session_set-2-requested_duration': '3600', + 'session_set-2-on_agenda': True, + 'session_set-2-remote_instructions': '', + 'session_set-2-attendees': attendees, + 'session_set-2-comments': '', + 'session_set-2-DELETE': '', + 'submit': 'Continue'} + self.client.login(username="ameschairman", password="ameschairman+password") + # submit + r = self.client.post(url,post_data) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertTrue('Confirm' in str(q("title")), r.context['form'].errors) + # confirm + post_data['submit'] = 'Submit' + r = self.client.post(confirm_url,post_data) + self.assertRedirects(r, reverse('ietf.secr.sreq.views.main')) + self.assertEqual(len(outbox),len_before+1) + notification = outbox[-1] + notification_payload = get_payload_text(notification) + sessions = Session.objects.filter(meeting=meeting,group=group) + self.assertEqual(len(sessions), 3) + session = sessions[0] + + self.assertEqual(session.resources.count(),1) + self.assertEqual(session.people_constraints.count(),1) + self.assertEqual(session.constraints().get(name='time_relation').time_relation, 'subsequent-days') + self.assertEqual(session.constraints().get(name='wg_adjacent').target.acronym, group2.acronym) + self.assertEqual( + list(session.constraints().get(name='timerange').timeranges.all().values('name')), + list(TimerangeName.objects.filter(name__in=['thursday-afternoon-early', 'thursday-afternoon-late']).values('name')) + ) + resource = session.resources.first() + self.assertTrue(resource.desc in notification_payload) + self.assertTrue('Schedule the sessions on subsequent days' in notification_payload) + self.assertTrue(group2.acronym in notification_payload) + self.assertTrue("Can't meet: Thursday early afternoon, Thursday late" in notification_payload) + self.assertTrue('Second session joint with: {}'.format(group3.acronym) in notification_payload) + self.assertTrue(ad.ascii_name() in notification_payload) + self.assertIn(ConstraintName.objects.get(slug='chair_conflict').name, notification_payload) + self.assertIn(group.acronym, notification_payload) + self.assertIn('1 Hour, 1 Hour, 1 Hour', notification_payload) + self.assertIn('The third session requires your approval', notification_payload) class LockAppTestCase(TestCase): def setUp(self): @@ -747,8 +868,8 @@ class SessionFormTest(TestCase): # Test with two sessions self.valid_form_data.update({ - 'length_session3': '', 'third_session': '', + 'session_set-TOTAL_FORMS': '2', 'joint_for_session': '2' }) form = SessionForm(data=self.valid_form_data, group=self.group1, meeting=self.meeting) @@ -756,8 +877,8 @@ class SessionFormTest(TestCase): # Test with one session self.valid_form_data.update({ - 'length_session2': '', 'num_session': 1, + 'session_set-TOTAL_FORMS': '1', 'joint_for_session': '1', 'session_time_relation': '', }) @@ -806,7 +927,7 @@ class SessionFormTest(TestCase): def test_invalid_session_time_relation(self): form = self._invalid_test_helper({ 'third_session': '', - 'length_session2': '', + 'session_set-TOTAL_FORMS': 1, 'num_session': 1, 'joint_for_session': '1', }) diff --git a/ietf/secr/sreq/views.py b/ietf/secr/sreq/views.py index 9200ea106..dfac32363 100644 --- a/ietf/secr/sreq/views.py +++ b/ietf/secr/sreq/views.py @@ -141,10 +141,11 @@ def save_conflicts(group, meeting, conflicts, name): name=constraint_name) constraint.save() -def send_notification(group,meeting,login,session,action): +def send_notification(group, meeting, login, sreq_data, session_data, action): ''' This function generates email notifications for various session request activities. - session argument is a dictionary of fields from the session request form + sreq_data argument is a dictionary of fields from the session request form + session_data is an array of data from individual session subforms action argument is a string [new|update]. ''' (to_email, cc_list) = gather_address_lists('session_requested',group=group,person=login) @@ -154,7 +155,7 @@ def send_notification(group,meeting,login,session,action): # send email context = {} - context['session'] = session + context['session'] = sreq_data context['group'] = group context['meeting'] = meeting context['login'] = login @@ -168,12 +169,14 @@ def send_notification(group,meeting,login,session,action): # if third session requested approval is required # change headers TO=ADs, CC=session-request, submitter and cochairs - if session.get('length_session3',None): - context['session']['num_session'] = 3 + if len(session_data) > 2: (to_email, cc_list) = gather_address_lists('session_requested_long',group=group,person=login) subject = '%s - Request for meeting session approval for IETF %s' % (group.acronym, meeting.number) template = 'sreq/session_approval_notification.txt' #status_text = 'the %s Directors for approval' % group.parent + + context['session_lengths'] = [sd['requested_duration'] for sd in session_data] + send_mail(None, to_email, from_email, @@ -368,7 +371,14 @@ def confirm(request, acronym): # send notification session_data['outbound_conflicts'] = [f"{d['name']}: {d['groups']}" for d in outbound_conflicts] - send_notification(group,meeting,login,session_data,'new') + send_notification( + group, + meeting, + login, + session_data, + [sf.cleaned_data for sf in form.session_forms[:num_sessions]], + 'new', + ) status_text = 'IETF Agenda to be scheduled' messages.success(request, 'Your request has been sent to %s' % status_text) @@ -537,7 +547,14 @@ def edit(request, acronym, num=None): #add_session_activity(group,'Session Request was updated',meeting,user) # send notification - send_notification(group,meeting,login,form.cleaned_data,'update') + send_notification( + group, + meeting, + login, + form.cleaned_data, + [sf.cleaned_data for sf in form.session_forms.forms_to_keep], + 'update', + ) messages.success(request, 'Session Request updated') return redirect('ietf.secr.sreq.views.view', acronym=acronym) diff --git a/ietf/secr/templates/includes/session_info.txt b/ietf/secr/templates/includes/session_info.txt index 80910a593..eea4a5f17 100644 --- a/ietf/secr/templates/includes/session_info.txt +++ b/ietf/secr/templates/includes/session_info.txt @@ -6,7 +6,7 @@ Session Requester: {{ login }} {% if session.joint_with_groups %}{{ session.joint_for_session_display }} joint with: {{ session.joint_with_groups }}{% endif %} Number of Sessions: {{ session.num_session }} -Length of Session(s): {{ session.length_session1|display_duration }}{% if session.length_session2 %}, {{ session.length_session2|display_duration }}{% endif %}{% if session.length_session3 %}, {{ session.length_session3|display_duration }}{% endif %} +Length of Session(s): {% for session_length in session_lengths %}{{ session_length.total_seconds|display_duration }}{% if not forloop.last %}, {% endif %}{% endfor %} Number of Attendees: {{ session.attendees }} Conflicts to Avoid: {% for line in session.outbound_conflicts %} {{line}}