Skip to content

Commit 0b49f40

Browse files
committed
Combined defer/undefer tests from doc/tests_ballot and iesg/tests, extending them to demonstrate current reported bugs.
Made doc.active_defer_event() look for the events that are currently being created. This remains brittle. Added email notifying the IESG of an undefer analagous to the defer email. Guarded against deferring an already deferred document or undeferring a document that hasn't been deferred. Guarded against deferring a document that's not scheduled for a telechat. Fixes bugs 1417, 1465, 1417 Commit ready for merge. - Legacy-Id: 8255
1 parent f7f29a6 commit 0b49f40

7 files changed

Lines changed: 155 additions & 151 deletions

File tree

ietf/doc/mails.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,18 @@ def email_ballot_deferred(request, doc, by, telechat_date):
311311
"doc/mail/ballot_deferred_email.txt",
312312
dict(doc=doc,
313313
by=by,
314+
action='deferred',
315+
telechat_date=telechat_date))
316+
317+
def email_ballot_undeferred(request, doc, by, telechat_date):
318+
to = "iesg@ietf.org"
319+
frm = "DraftTracker Mail System <iesg-secretary@ietf.org>"
320+
send_mail(request, to, frm,
321+
"IESG Undeferred Ballot notification: %s" % doc.file_tag(),
322+
"doc/mail/ballot_deferred_email.txt",
323+
dict(doc=doc,
324+
by=by,
325+
action='undeferred',
314326
telechat_date=telechat_date))
315327

316328
def generate_issue_ballot_mail(request, doc, ballot):

ietf/doc/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,9 +387,9 @@ def returning_item(self):
387387
# isn't this just returning whether the state is currently a defer state for that document type?
388388
def active_defer_event(self):
389389
if self.type_id == "draft" and self.get_state_slug("draft-iesg") == "defer":
390-
return self.latest_event(type="changed_document", desc__startswith="State changed to <b>IESG Evaluation - Defer</b>")
390+
return self.latest_event(type="changed_state", desc__icontains="State changed to <b>IESG Evaluation - Defer</b>")
391391
elif self.type_id == "conflrev" and self.get_state_slug("conflrev") == "defer":
392-
return self.latest_event(type="changed_document", desc__startswith="State changed to <b>IESG Evaluation - Defer</b>")
392+
return self.latest_event(type="changed_state", desc__icontains="State changed to <b>IESG Evaluation - Defer</b>")
393393
return None
394394

395395
def most_recent_ietflc(self):

ietf/doc/tests_ballot.py

Lines changed: 126 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
from django.core.urlresolvers import reverse as urlreverse
77

88
from ietf.doc.models import ( Document, State, DocEvent, BallotDocEvent,
9-
BallotPositionDocEvent, LastCallDocEvent, WriteupDocEvent )
9+
BallotPositionDocEvent, LastCallDocEvent, WriteupDocEvent, TelechatDocEvent )
1010
from ietf.group.models import Group, Role
1111
from ietf.name.models import BallotPositionName
12+
from ietf.iesg.models import TelechatDate
1213
from ietf.person.models import Person
1314
from ietf.utils.test_utils import TestCase
1415
from ietf.utils.mail import outbox
@@ -162,52 +163,6 @@ def test_send_ballot_comment(self):
162163
self.assertTrue("clearer title" in str(m))
163164
self.assertTrue("Test!" in str(m))
164165

165-
166-
class DeferBallotTests(TestCase):
167-
def test_defer_ballot(self):
168-
draft = make_test_data()
169-
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva"))
170-
171-
url = urlreverse('doc_defer_ballot', kwargs=dict(name=draft.name))
172-
login_testing_unauthorized(self, "ad", url)
173-
174-
# normal get
175-
r = self.client.get(url)
176-
self.assertEqual(r.status_code, 200)
177-
178-
# defer
179-
mailbox_before = len(outbox)
180-
181-
r = self.client.post(url, dict())
182-
self.assertEqual(r.status_code, 302)
183-
184-
draft = Document.objects.get(name=draft.name)
185-
self.assertEqual(draft.get_state_slug("draft-iesg"), "defer")
186-
187-
self.assertEqual(len(outbox), mailbox_before + 2)
188-
self.assertTrue("State Update" in outbox[-2]['Subject'])
189-
self.assertTrue("Deferred" in outbox[-1]['Subject'])
190-
self.assertTrue(draft.file_tag() in outbox[-1]['Subject'])
191-
192-
def test_undefer_ballot(self):
193-
draft = make_test_data()
194-
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="defer"))
195-
196-
url = urlreverse('doc_undefer_ballot', kwargs=dict(name=draft.name))
197-
login_testing_unauthorized(self, "ad", url)
198-
199-
# normal get
200-
r = self.client.get(url)
201-
self.assertEqual(r.status_code, 200)
202-
203-
# undefer
204-
r = self.client.post(url, dict())
205-
self.assertEqual(r.status_code, 302)
206-
207-
draft = Document.objects.get(name=draft.name)
208-
self.assertEqual(draft.get_state_slug("draft-iesg"), "iesg-eva")
209-
210-
211166
class BallotWriteupsTests(TestCase):
212167
def test_edit_last_call_text(self):
213168
draft = make_test_data()
@@ -482,3 +437,127 @@ def test_make_last_call(self):
482437
self.assertTrue("Last Call" in outbox[-3]['Subject'])
483438
self.assertTrue("Last Call" in draft.message_set.order_by("-time")[0].subject)
484439

440+
class DeferUndeferTestCase(TestCase):
441+
def helper_test_defer(self,name):
442+
443+
doc = Document.objects.get(name=name)
444+
url = urlreverse('doc_defer_ballot',kwargs=dict(name=doc.name))
445+
446+
login_testing_unauthorized(self, "ad", url)
447+
448+
# Verify that you can't defer a document that's not on a telechat
449+
r = self.client.post(url,dict())
450+
self.assertEqual(r.status_code, 404)
451+
452+
# Put the document on a telechat
453+
dates = TelechatDate.objects.active().order_by("date")
454+
first_date = dates[0].date
455+
second_date = dates[1].date
456+
457+
e = TelechatDocEvent(type="scheduled_for_telechat",
458+
doc = doc,
459+
by = Person.objects.get(name="Aread Irector"),
460+
telechat_date = first_date,
461+
returning_item = False,
462+
)
463+
e.save()
464+
465+
# get
466+
r = self.client.get(url)
467+
self.assertEqual(r.status_code, 200)
468+
q = PyQuery(r.content)
469+
self.assertEqual(len(q('form.defer')),1)
470+
471+
# defer
472+
mailbox_before = len(outbox)
473+
self.assertEqual(doc.telechat_date(), first_date)
474+
r = self.client.post(url,dict())
475+
self.assertEqual(r.status_code, 302)
476+
doc = Document.objects.get(name=name)
477+
self.assertEqual(doc.telechat_date(), second_date)
478+
self.assertTrue(doc.returning_item())
479+
defer_states = dict(draft=['draft-iesg','defer'],conflrev=['conflrev','defer'])
480+
if doc.type_id in defer_states:
481+
self.assertEqual(doc.get_state(defer_states[doc.type_id][0]).slug,defer_states[doc.type_id][1])
482+
self.assertTrue(doc.active_defer_event())
483+
self.assertEqual(len(outbox), mailbox_before + 2)
484+
self.assertTrue("State Update" in outbox[-2]['Subject'])
485+
self.assertTrue("Deferred" in outbox[-1]['Subject'])
486+
self.assertTrue(doc.file_tag() in outbox[-1]['Subject'])
487+
488+
# Ensure it's not possible to defer again
489+
r = self.client.get(url)
490+
self.assertEqual(r.status_code, 404)
491+
r = self.client.post(url,dict())
492+
self.assertEqual(r.status_code, 404)
493+
494+
495+
def helper_test_undefer(self,name):
496+
497+
doc = Document.objects.get(name=name)
498+
url = urlreverse('doc_undefer_ballot',kwargs=dict(name=doc.name))
499+
500+
login_testing_unauthorized(self, "ad", url)
501+
502+
# some additional setup
503+
dates = TelechatDate.objects.active().order_by("date")
504+
first_date = dates[0].date
505+
second_date = dates[1].date
506+
507+
e = TelechatDocEvent(type="scheduled_for_telechat",
508+
doc = doc,
509+
by = Person.objects.get(name="Aread Irector"),
510+
telechat_date = second_date,
511+
returning_item = True,
512+
)
513+
e.save()
514+
defer_states = dict(draft=['draft-iesg','defer'],conflrev=['conflrev','defer'])
515+
if doc.type_id in defer_states:
516+
doc.set_state(State.objects.get(used=True, type=defer_states[doc.type_id][0],slug=defer_states[doc.type_id][1]))
517+
doc.save()
518+
519+
# get
520+
r = self.client.get(url)
521+
self.assertEqual(r.status_code, 200)
522+
q = PyQuery(r.content)
523+
self.assertEqual(len(q('form.undefer')),1)
524+
525+
# undefer
526+
mailbox_before = len(outbox)
527+
self.assertEqual(doc.telechat_date(), second_date)
528+
r = self.client.post(url,dict())
529+
self.assertEqual(r.status_code, 302)
530+
doc = Document.objects.get(name=name)
531+
self.assertEqual(doc.telechat_date(), first_date)
532+
self.assertTrue(doc.returning_item())
533+
undefer_states = dict(draft=['draft-iesg','iesg-eva'],conflrev=['conflrev','iesgeval'])
534+
if doc.type_id in undefer_states:
535+
self.assertEqual(doc.get_state(undefer_states[doc.type_id][0]).slug,undefer_states[doc.type_id][1])
536+
self.assertFalse(doc.active_defer_event())
537+
self.assertEqual(len(outbox), mailbox_before + 2)
538+
self.assertTrue("State Update" in outbox[-2]['Subject'])
539+
self.assertTrue("Undeferred" in outbox[-1]['Subject'])
540+
self.assertTrue(doc.file_tag() in outbox[-1]['Subject'])
541+
542+
# Ensure it's not possible to undefer again
543+
r = self.client.get(url)
544+
self.assertEqual(r.status_code, 404)
545+
r = self.client.post(url,dict())
546+
self.assertEqual(r.status_code, 404)
547+
548+
def test_defer_draft(self):
549+
self.helper_test_defer('draft-ietf-mars-test')
550+
551+
def test_defer_conflict_review(self):
552+
self.helper_test_defer('conflict-review-imaginary-irtf-submission')
553+
554+
def test_undefer_draft(self):
555+
self.helper_test_undefer('draft-ietf-mars-test')
556+
557+
def test_undefer_conflict_review(self):
558+
self.helper_test_undefer('conflict-review-imaginary-irtf-submission')
559+
560+
# when charters support being deferred, be sure to test them here
561+
562+
def setUp(self):
563+
make_test_data()

ietf/doc/views_ballot.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
BallotType, LastCallDocEvent, WriteupDocEvent, save_document_in_history, IESG_SUBSTATE_TAGS )
1818
from ietf.doc.utils import ( add_state_change_event, close_ballot, close_open_ballots,
1919
create_ballot_if_not_open, update_telechat )
20-
from ietf.doc.mails import ( email_ad, email_ballot_deferred, email_state_changed,
21-
extra_automation_headers, generate_last_call_announcement, generate_issue_ballot_mail,
22-
generate_ballot_writeup, generate_approval_mail )
20+
from ietf.doc.mails import ( email_ad, email_ballot_deferred, email_ballot_undeferred,
21+
email_state_changed, extra_automation_headers, generate_last_call_announcement,
22+
generate_issue_ballot_mail, generate_ballot_writeup, generate_approval_mail )
2323
from ietf.doc.lastcall import request_last_call
2424
from ietf.iesg.models import TelechatDate
2525
from ietf.ietfauth.utils import has_role, role_required
@@ -69,6 +69,7 @@ def do_undefer_ballot(request, doc):
6969

7070
update_telechat(request, doc, login, telechat_date)
7171
email_state_changed(request, doc, e.desc)
72+
email_ballot_undeferred(request, doc, login.plain_name(), telechat_date)
7273

7374
def position_to_ballot_choice(position):
7475
for v, label in BALLOT_CHOICES:
@@ -335,7 +336,9 @@ def defer_ballot(request, name):
335336
doc = get_object_or_404(Document, docalias__name=name)
336337
if doc.type_id not in ('draft','conflrev'):
337338
raise Http404()
338-
if doc.type_id == 'draft' and not doc.get_state("draft-iesg"):
339+
interesting_state = dict(draft='draft-iesg',conflrev='conflrev')
340+
state = doc.get_state(interesting_state[doc.type_id])
341+
if not state or state.slug=='defer' or not doc.telechat_date():
339342
raise Http404()
340343

341344
login = request.user.person
@@ -384,6 +387,10 @@ def undefer_ballot(request, name):
384387
raise Http404()
385388
if doc.type_id == 'draft' and not doc.get_state("draft-iesg"):
386389
raise Http404()
390+
interesting_state = dict(draft='draft-iesg',conflrev='conflrev')
391+
state = doc.get_state(interesting_state[doc.type_id])
392+
if not state or state.slug!='defer':
393+
raise Http404()
387394

388395
telechat_date = TelechatDate.objects.active().order_by("date")[0].date
389396

ietf/iesg/tests.py

Lines changed: 0 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -442,99 +442,3 @@ def test_reschedule(self):
442442
self.assertTrue(not draft.latest_event(TelechatDocEvent, "scheduled_for_telechat").returning_item)
443443
self.assertEqual(draft.docevent_set.count(), events_before + 1)
444444

445-
class DeferUndeferTestCase(TestCase):
446-
def helper_test_defer(self,name):
447-
448-
doc = Document.objects.get(name=name)
449-
url = urlreverse('doc_defer_ballot',kwargs=dict(name=doc.name))
450-
451-
login_testing_unauthorized(self, "ad", url)
452-
453-
# some additional setup
454-
dates = TelechatDate.objects.active().order_by("date")
455-
first_date = dates[0].date
456-
second_date = dates[1].date
457-
458-
e = TelechatDocEvent(type="scheduled_for_telechat",
459-
doc = doc,
460-
by = Person.objects.get(name="Aread Irector"),
461-
telechat_date = first_date,
462-
returning_item = False,
463-
)
464-
e.save()
465-
466-
# get
467-
r = self.client.get(url)
468-
self.assertEqual(r.status_code, 200)
469-
q = PyQuery(r.content)
470-
self.assertEqual(len(q('form.defer')),1)
471-
472-
# defer
473-
self.assertEqual(doc.telechat_date(), first_date)
474-
r = self.client.post(url,dict())
475-
self.assertEqual(r.status_code, 302)
476-
doc = Document.objects.get(name=name)
477-
self.assertEqual(doc.telechat_date(), second_date)
478-
self.assertTrue(doc.returning_item())
479-
defer_states = dict(draft=['draft-iesg','defer'],conflrev=['conflrev','defer'])
480-
if doc.type_id in defer_states:
481-
self.assertEqual(doc.get_state(defer_states[doc.type_id][0]).slug,defer_states[doc.type_id][1])
482-
483-
484-
def helper_test_undefer(self,name):
485-
486-
doc = Document.objects.get(name=name)
487-
url = urlreverse('doc_undefer_ballot',kwargs=dict(name=doc.name))
488-
489-
login_testing_unauthorized(self, "ad", url)
490-
491-
# some additional setup
492-
dates = TelechatDate.objects.active().order_by("date")
493-
first_date = dates[0].date
494-
second_date = dates[1].date
495-
496-
e = TelechatDocEvent(type="scheduled_for_telechat",
497-
doc = doc,
498-
by = Person.objects.get(name="Aread Irector"),
499-
telechat_date = second_date,
500-
returning_item = True,
501-
)
502-
e.save()
503-
defer_states = dict(draft=['draft-iesg','defer'],conflrev=['conflrev','defer'])
504-
if doc.type_id in defer_states:
505-
doc.set_state(State.objects.get(used=True, type=defer_states[doc.type_id][0],slug=defer_states[doc.type_id][1]))
506-
doc.save()
507-
508-
# get
509-
r = self.client.get(url)
510-
self.assertEqual(r.status_code, 200)
511-
q = PyQuery(r.content)
512-
self.assertEqual(len(q('form.undefer')),1)
513-
514-
# undefer
515-
self.assertEqual(doc.telechat_date(), second_date)
516-
r = self.client.post(url,dict())
517-
self.assertEqual(r.status_code, 302)
518-
doc = Document.objects.get(name=name)
519-
self.assertEqual(doc.telechat_date(), first_date)
520-
self.assertTrue(doc.returning_item())
521-
undefer_states = dict(draft=['draft-iesg','iesg-eva'],conflrev=['conflrev','iesgeval'])
522-
if doc.type_id in undefer_states:
523-
self.assertEqual(doc.get_state(undefer_states[doc.type_id][0]).slug,undefer_states[doc.type_id][1])
524-
525-
def test_defer_draft(self):
526-
self.helper_test_defer('draft-ietf-mars-test')
527-
528-
def test_defer_conflict_review(self):
529-
self.helper_test_defer('conflict-review-imaginary-irtf-submission')
530-
531-
def test_undefer_draft(self):
532-
self.helper_test_undefer('draft-ietf-mars-test')
533-
534-
def test_undefer_conflict_review(self):
535-
self.helper_test_undefer('conflict-review-imaginary-irtf-submission')
536-
537-
# when charters support being deferred, be sure to test them here
538-
539-
def setUp(self):
540-
make_test_data()

ietf/templates/doc/document_ballot_content.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
<div><a href="{% url "doc_undefer_ballot" name=doc.name %}">Undefer ballot</a></div>
1414
<div>Ballot deferred by {{ deferred.by }} on {{ deferred.time|date:"Y-m-d" }}.</div>
1515
{% else %}
16-
<div><a href="{% url "doc_defer_ballot" name=doc.name %}">Defer ballot</a></div>
16+
{% if doc.telechat_date %}
17+
<div><a href="{% url "doc_defer_ballot" name=doc.name %}">Defer ballot</a></div>
18+
{% endif %}
1719
{% endif %}
1820
{% if user|has_role:"Secretariat" %}
1921
<div><a href="{% url "doc_clear_ballot" name=doc.name %}">Clear ballot</a></div>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{% autoescape off %}{% filter wordwrap:73 %}Ballot of {{ doc.file_tag }} has been deferred by {{ by }}.{% endfilter %}
1+
{% autoescape off %}{% filter wordwrap:73 %}Ballot of {{ doc.file_tag }} has been {{action}} by {{ by }}.{% endfilter %}
22

33
This ballot will be on the IESG agenda of {{ telechat_date }}.
44
{% endautoescape %}

0 commit comments

Comments
 (0)