From 9ab820fca9d7b0d8c541e8dcb14495b830fef41f Mon Sep 17 00:00:00 2001 From: Paul Selkirk Date: Tue, 20 Feb 2024 10:30:41 -0500 Subject: [PATCH] fix: Expand and enforce Cancel Interim Meeting Request comments length to 512 (#7069) * fix: Expand and enforce Cancel Interim Meeting Request comments length to 512 (#6998) * fix: Verify comment text in generated email --- ietf/meeting/forms.py | 3 ++- .../0005_alter_session_agenda_note.py | 18 ++++++++++++++++++ ietf/meeting/models.py | 2 +- ietf/meeting/tests_views.py | 12 +++++++++++- .../interim_meeting_cancellation_notice.txt | 2 +- 5 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 ietf/meeting/migrations/0005_alter_session_agenda_note.py diff --git a/ietf/meeting/forms.py b/ietf/meeting/forms.py index ef6a2721e..dfc765ad2 100644 --- a/ietf/meeting/forms.py +++ b/ietf/meeting/forms.py @@ -380,7 +380,8 @@ class InterimAnnounceForm(forms.ModelForm): class InterimCancelForm(forms.Form): group = forms.CharField(max_length=255, required=False) date = forms.DateField(required=False) - comments = forms.CharField(required=False, widget=forms.Textarea(attrs={'placeholder': 'enter optional comments here'}), strip=False) + # max_length must match Session.agenda_note + comments = forms.CharField(max_length=512, required=False, widget=forms.Textarea(attrs={'placeholder': 'enter optional comments here'}), strip=False) def __init__(self, *args, **kwargs): super(InterimCancelForm, self).__init__(*args, **kwargs) diff --git a/ietf/meeting/migrations/0005_alter_session_agenda_note.py b/ietf/meeting/migrations/0005_alter_session_agenda_note.py new file mode 100644 index 000000000..59daeea45 --- /dev/null +++ b/ietf/meeting/migrations/0005_alter_session_agenda_note.py @@ -0,0 +1,18 @@ +# Copyright The IETF Trust 2024, All Rights Reserved + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("meeting", "0004_session_chat_room"), + ] + + operations = [ + migrations.AlterField( + model_name="session", + name="agenda_note", + field=models.CharField(blank=True, max_length=512), + ), + ] diff --git a/ietf/meeting/models.py b/ietf/meeting/models.py index de9613de1..ca137fc0d 100644 --- a/ietf/meeting/models.py +++ b/ietf/meeting/models.py @@ -1017,7 +1017,7 @@ class Session(models.Model): group = ForeignKey(Group) # The group type historically determined the session type. BOFs also need to be added as a group. Note that not all meeting requests have a natural group to associate with. joint_with_groups = models.ManyToManyField(Group, related_name='sessions_joint_in',blank=True) attendees = models.IntegerField(null=True, blank=True) - agenda_note = models.CharField(blank=True, max_length=255) + agenda_note = models.CharField(blank=True, max_length=512) requested_duration = models.DurationField(default=datetime.timedelta(0)) comments = models.TextField(blank=True) scheduled = models.DateTimeField(null=True, blank=True) diff --git a/ietf/meeting/tests_views.py b/ietf/meeting/tests_views.py index a57fcf63c..2459eb14c 100644 --- a/ietf/meeting/tests_views.py +++ b/ietf/meeting/tests_views.py @@ -5595,8 +5595,17 @@ class InterimTests(TestCase): self.assertEqual(r.status_code, 403) self.assertFalse(mock.called, 'Should not cancel sessions if request rejected') - # test cancelling before announcement + # test with overly-long comments + comments += '0123456789abcdef'*32 self.client.login(username="marschairman", password="marschairman+password") + r = self.client.post(url, {'comments': comments}) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertTrue(q('form .is-invalid')) + # truncate to max_length + comments = comments[:512] + + # test cancelling before announcement length_before = len(outbox) r = self.client.post(url, {'comments': comments}) self.assertRedirects(r, urlreverse('ietf.meeting.views.upcoming')) @@ -5618,6 +5627,7 @@ class InterimTests(TestCase): self.assertEqual(session.agenda_note, comments) self.assertEqual(len(outbox), length_before + 1) self.assertIn('Interim Meeting Cancelled', outbox[-1]['Subject']) + self.assertIn(comments, get_payload_text(outbox[-1])) self.assertTrue(mock.called, 'Should cancel sessions if request handled') self.assertCountEqual(mock.call_args[0][1], meeting.session_set.all()) diff --git a/ietf/templates/meeting/interim_meeting_cancellation_notice.txt b/ietf/templates/meeting/interim_meeting_cancellation_notice.txt index d4774c168..83f29bf1e 100644 --- a/ietf/templates/meeting/interim_meeting_cancellation_notice.txt +++ b/ietf/templates/meeting/interim_meeting_cancellation_notice.txt @@ -3,6 +3,6 @@ The {{ group.name }} ({{ group.acronym }}) {% if not meeting.city %}virtual {% e interim meeting for {{ meeting.date|date:"Y-m-d" }} from {{ start_time|time:"H:i" }} to {{ end_time|time:"H:i" }} {{ meeting.time_zone }} has been cancelled. -{{ meeting.session_set.0.agenda_note }} +{{ meeting.session_set.first.agenda_note }} {% endtimezone %}