Merged in [8255] from rjsparks@nostrum.com:\n 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
 - Legacy-Id: 8366
Note: SVN reference [8255] has been migrated to Git commit 0b49f402b4ec9145cb290b8a968755cc9ebdef92
This commit is contained in:
Henrik Levkowetz 2014-09-28 18:59:10 +00:00
parent 4cc4f5080c
commit cea60ad8df
7 changed files with 155 additions and 151 deletions

View file

@ -311,6 +311,18 @@ def email_ballot_deferred(request, doc, by, telechat_date):
"doc/mail/ballot_deferred_email.txt",
dict(doc=doc,
by=by,
action='deferred',
telechat_date=telechat_date))
def email_ballot_undeferred(request, doc, by, telechat_date):
to = "iesg@ietf.org"
frm = "DraftTracker Mail System <iesg-secretary@ietf.org>"
send_mail(request, to, frm,
"IESG Undeferred Ballot notification: %s" % doc.file_tag(),
"doc/mail/ballot_deferred_email.txt",
dict(doc=doc,
by=by,
action='undeferred',
telechat_date=telechat_date))
def generate_issue_ballot_mail(request, doc, ballot):

View file

@ -387,9 +387,9 @@ class Document(DocumentInfo):
# isn't this just returning whether the state is currently a defer state for that document type?
def active_defer_event(self):
if self.type_id == "draft" and self.get_state_slug("draft-iesg") == "defer":
return self.latest_event(type="changed_document", desc__startswith="State changed to <b>IESG Evaluation - Defer</b>")
return self.latest_event(type="changed_state", desc__icontains="State changed to <b>IESG Evaluation - Defer</b>")
elif self.type_id == "conflrev" and self.get_state_slug("conflrev") == "defer":
return self.latest_event(type="changed_document", desc__startswith="State changed to <b>IESG Evaluation - Defer</b>")
return self.latest_event(type="changed_state", desc__icontains="State changed to <b>IESG Evaluation - Defer</b>")
return None
def most_recent_ietflc(self):

View file

@ -6,9 +6,10 @@ import debug # pyflakes:ignore
from django.core.urlresolvers import reverse as urlreverse
from ietf.doc.models import ( Document, State, DocEvent, BallotDocEvent,
BallotPositionDocEvent, LastCallDocEvent, WriteupDocEvent )
BallotPositionDocEvent, LastCallDocEvent, WriteupDocEvent, TelechatDocEvent )
from ietf.group.models import Group, Role
from ietf.name.models import BallotPositionName
from ietf.iesg.models import TelechatDate
from ietf.person.models import Person
from ietf.utils.test_utils import TestCase
from ietf.utils.mail import outbox
@ -162,52 +163,6 @@ class EditPositionTests(TestCase):
self.assertTrue("clearer title" in str(m))
self.assertTrue("Test!" in str(m))
class DeferBallotTests(TestCase):
def test_defer_ballot(self):
draft = make_test_data()
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva"))
url = urlreverse('doc_defer_ballot', kwargs=dict(name=draft.name))
login_testing_unauthorized(self, "ad", url)
# normal get
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
# defer
mailbox_before = len(outbox)
r = self.client.post(url, dict())
self.assertEqual(r.status_code, 302)
draft = Document.objects.get(name=draft.name)
self.assertEqual(draft.get_state_slug("draft-iesg"), "defer")
self.assertEqual(len(outbox), mailbox_before + 2)
self.assertTrue("State Update" in outbox[-2]['Subject'])
self.assertTrue("Deferred" in outbox[-1]['Subject'])
self.assertTrue(draft.file_tag() in outbox[-1]['Subject'])
def test_undefer_ballot(self):
draft = make_test_data()
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="defer"))
url = urlreverse('doc_undefer_ballot', kwargs=dict(name=draft.name))
login_testing_unauthorized(self, "ad", url)
# normal get
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
# undefer
r = self.client.post(url, dict())
self.assertEqual(r.status_code, 302)
draft = Document.objects.get(name=draft.name)
self.assertEqual(draft.get_state_slug("draft-iesg"), "iesg-eva")
class BallotWriteupsTests(TestCase):
def test_edit_last_call_text(self):
draft = make_test_data()
@ -482,3 +437,127 @@ class MakeLastCallTests(TestCase):
self.assertTrue("Last Call" in outbox[-3]['Subject'])
self.assertTrue("Last Call" in draft.message_set.order_by("-time")[0].subject)
class DeferUndeferTestCase(TestCase):
def helper_test_defer(self,name):
doc = Document.objects.get(name=name)
url = urlreverse('doc_defer_ballot',kwargs=dict(name=doc.name))
login_testing_unauthorized(self, "ad", url)
# Verify that you can't defer a document that's not on a telechat
r = self.client.post(url,dict())
self.assertEqual(r.status_code, 404)
# Put the document on a telechat
dates = TelechatDate.objects.active().order_by("date")
first_date = dates[0].date
second_date = dates[1].date
e = TelechatDocEvent(type="scheduled_for_telechat",
doc = doc,
by = Person.objects.get(name="Aread Irector"),
telechat_date = first_date,
returning_item = False,
)
e.save()
# get
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)
self.assertEqual(len(q('form.defer')),1)
# defer
mailbox_before = len(outbox)
self.assertEqual(doc.telechat_date(), first_date)
r = self.client.post(url,dict())
self.assertEqual(r.status_code, 302)
doc = Document.objects.get(name=name)
self.assertEqual(doc.telechat_date(), second_date)
self.assertTrue(doc.returning_item())
defer_states = dict(draft=['draft-iesg','defer'],conflrev=['conflrev','defer'])
if doc.type_id in defer_states:
self.assertEqual(doc.get_state(defer_states[doc.type_id][0]).slug,defer_states[doc.type_id][1])
self.assertTrue(doc.active_defer_event())
self.assertEqual(len(outbox), mailbox_before + 2)
self.assertTrue("State Update" in outbox[-2]['Subject'])
self.assertTrue("Deferred" in outbox[-1]['Subject'])
self.assertTrue(doc.file_tag() in outbox[-1]['Subject'])
# Ensure it's not possible to defer again
r = self.client.get(url)
self.assertEqual(r.status_code, 404)
r = self.client.post(url,dict())
self.assertEqual(r.status_code, 404)
def helper_test_undefer(self,name):
doc = Document.objects.get(name=name)
url = urlreverse('doc_undefer_ballot',kwargs=dict(name=doc.name))
login_testing_unauthorized(self, "ad", url)
# some additional setup
dates = TelechatDate.objects.active().order_by("date")
first_date = dates[0].date
second_date = dates[1].date
e = TelechatDocEvent(type="scheduled_for_telechat",
doc = doc,
by = Person.objects.get(name="Aread Irector"),
telechat_date = second_date,
returning_item = True,
)
e.save()
defer_states = dict(draft=['draft-iesg','defer'],conflrev=['conflrev','defer'])
if doc.type_id in defer_states:
doc.set_state(State.objects.get(used=True, type=defer_states[doc.type_id][0],slug=defer_states[doc.type_id][1]))
doc.save()
# get
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)
self.assertEqual(len(q('form.undefer')),1)
# undefer
mailbox_before = len(outbox)
self.assertEqual(doc.telechat_date(), second_date)
r = self.client.post(url,dict())
self.assertEqual(r.status_code, 302)
doc = Document.objects.get(name=name)
self.assertEqual(doc.telechat_date(), first_date)
self.assertTrue(doc.returning_item())
undefer_states = dict(draft=['draft-iesg','iesg-eva'],conflrev=['conflrev','iesgeval'])
if doc.type_id in undefer_states:
self.assertEqual(doc.get_state(undefer_states[doc.type_id][0]).slug,undefer_states[doc.type_id][1])
self.assertFalse(doc.active_defer_event())
self.assertEqual(len(outbox), mailbox_before + 2)
self.assertTrue("State Update" in outbox[-2]['Subject'])
self.assertTrue("Undeferred" in outbox[-1]['Subject'])
self.assertTrue(doc.file_tag() in outbox[-1]['Subject'])
# Ensure it's not possible to undefer again
r = self.client.get(url)
self.assertEqual(r.status_code, 404)
r = self.client.post(url,dict())
self.assertEqual(r.status_code, 404)
def test_defer_draft(self):
self.helper_test_defer('draft-ietf-mars-test')
def test_defer_conflict_review(self):
self.helper_test_defer('conflict-review-imaginary-irtf-submission')
def test_undefer_draft(self):
self.helper_test_undefer('draft-ietf-mars-test')
def test_undefer_conflict_review(self):
self.helper_test_undefer('conflict-review-imaginary-irtf-submission')
# when charters support being deferred, be sure to test them here
def setUp(self):
make_test_data()

View file

@ -17,9 +17,9 @@ from ietf.doc.models import ( Document, State, DocEvent, BallotDocEvent, BallotP
BallotType, LastCallDocEvent, WriteupDocEvent, save_document_in_history, IESG_SUBSTATE_TAGS )
from ietf.doc.utils import ( add_state_change_event, close_ballot, close_open_ballots,
create_ballot_if_not_open, update_telechat )
from ietf.doc.mails import ( email_ad, email_ballot_deferred, email_state_changed,
extra_automation_headers, generate_last_call_announcement, generate_issue_ballot_mail,
generate_ballot_writeup, generate_approval_mail )
from ietf.doc.mails import ( email_ad, email_ballot_deferred, email_ballot_undeferred,
email_state_changed, extra_automation_headers, generate_last_call_announcement,
generate_issue_ballot_mail, generate_ballot_writeup, generate_approval_mail )
from ietf.doc.lastcall import request_last_call
from ietf.iesg.models import TelechatDate
from ietf.ietfauth.utils import has_role, role_required
@ -69,6 +69,7 @@ def do_undefer_ballot(request, doc):
update_telechat(request, doc, login, telechat_date)
email_state_changed(request, doc, e.desc)
email_ballot_undeferred(request, doc, login.plain_name(), telechat_date)
def position_to_ballot_choice(position):
for v, label in BALLOT_CHOICES:
@ -335,7 +336,9 @@ def defer_ballot(request, name):
doc = get_object_or_404(Document, docalias__name=name)
if doc.type_id not in ('draft','conflrev'):
raise Http404()
if doc.type_id == 'draft' and not doc.get_state("draft-iesg"):
interesting_state = dict(draft='draft-iesg',conflrev='conflrev')
state = doc.get_state(interesting_state[doc.type_id])
if not state or state.slug=='defer' or not doc.telechat_date():
raise Http404()
login = request.user.person
@ -384,6 +387,10 @@ def undefer_ballot(request, name):
raise Http404()
if doc.type_id == 'draft' and not doc.get_state("draft-iesg"):
raise Http404()
interesting_state = dict(draft='draft-iesg',conflrev='conflrev')
state = doc.get_state(interesting_state[doc.type_id])
if not state or state.slug!='defer':
raise Http404()
telechat_date = TelechatDate.objects.active().order_by("date")[0].date

View file

@ -442,99 +442,3 @@ class RescheduleOnAgendaTests(TestCase):
self.assertTrue(not draft.latest_event(TelechatDocEvent, "scheduled_for_telechat").returning_item)
self.assertEqual(draft.docevent_set.count(), events_before + 1)
class DeferUndeferTestCase(TestCase):
def helper_test_defer(self,name):
doc = Document.objects.get(name=name)
url = urlreverse('doc_defer_ballot',kwargs=dict(name=doc.name))
login_testing_unauthorized(self, "ad", url)
# some additional setup
dates = TelechatDate.objects.active().order_by("date")
first_date = dates[0].date
second_date = dates[1].date
e = TelechatDocEvent(type="scheduled_for_telechat",
doc = doc,
by = Person.objects.get(name="Aread Irector"),
telechat_date = first_date,
returning_item = False,
)
e.save()
# get
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)
self.assertEqual(len(q('form.defer')),1)
# defer
self.assertEqual(doc.telechat_date(), first_date)
r = self.client.post(url,dict())
self.assertEqual(r.status_code, 302)
doc = Document.objects.get(name=name)
self.assertEqual(doc.telechat_date(), second_date)
self.assertTrue(doc.returning_item())
defer_states = dict(draft=['draft-iesg','defer'],conflrev=['conflrev','defer'])
if doc.type_id in defer_states:
self.assertEqual(doc.get_state(defer_states[doc.type_id][0]).slug,defer_states[doc.type_id][1])
def helper_test_undefer(self,name):
doc = Document.objects.get(name=name)
url = urlreverse('doc_undefer_ballot',kwargs=dict(name=doc.name))
login_testing_unauthorized(self, "ad", url)
# some additional setup
dates = TelechatDate.objects.active().order_by("date")
first_date = dates[0].date
second_date = dates[1].date
e = TelechatDocEvent(type="scheduled_for_telechat",
doc = doc,
by = Person.objects.get(name="Aread Irector"),
telechat_date = second_date,
returning_item = True,
)
e.save()
defer_states = dict(draft=['draft-iesg','defer'],conflrev=['conflrev','defer'])
if doc.type_id in defer_states:
doc.set_state(State.objects.get(used=True, type=defer_states[doc.type_id][0],slug=defer_states[doc.type_id][1]))
doc.save()
# get
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)
self.assertEqual(len(q('form.undefer')),1)
# undefer
self.assertEqual(doc.telechat_date(), second_date)
r = self.client.post(url,dict())
self.assertEqual(r.status_code, 302)
doc = Document.objects.get(name=name)
self.assertEqual(doc.telechat_date(), first_date)
self.assertTrue(doc.returning_item())
undefer_states = dict(draft=['draft-iesg','iesg-eva'],conflrev=['conflrev','iesgeval'])
if doc.type_id in undefer_states:
self.assertEqual(doc.get_state(undefer_states[doc.type_id][0]).slug,undefer_states[doc.type_id][1])
def test_defer_draft(self):
self.helper_test_defer('draft-ietf-mars-test')
def test_defer_conflict_review(self):
self.helper_test_defer('conflict-review-imaginary-irtf-submission')
def test_undefer_draft(self):
self.helper_test_undefer('draft-ietf-mars-test')
def test_undefer_conflict_review(self):
self.helper_test_undefer('conflict-review-imaginary-irtf-submission')
# when charters support being deferred, be sure to test them here
def setUp(self):
make_test_data()

View file

@ -13,7 +13,9 @@
<div><a href="{% url "doc_undefer_ballot" name=doc.name %}">Undefer ballot</a></div>
<div>Ballot deferred by {{ deferred.by }} on {{ deferred.time|date:"Y-m-d" }}.</div>
{% else %}
<div><a href="{% url "doc_defer_ballot" name=doc.name %}">Defer ballot</a></div>
{% if doc.telechat_date %}
<div><a href="{% url "doc_defer_ballot" name=doc.name %}">Defer ballot</a></div>
{% endif %}
{% endif %}
{% if user|has_role:"Secretariat" %}
<div><a href="{% url "doc_clear_ballot" name=doc.name %}">Clear ballot</a></div>

View file

@ -1,4 +1,4 @@
{% autoescape off %}{% filter wordwrap:73 %}Ballot of {{ doc.file_tag }} has been deferred by {{ by }}.{% endfilter %}
{% autoescape off %}{% filter wordwrap:73 %}Ballot of {{ doc.file_tag }} has been {{action}} by {{ by }}.{% endfilter %}
This ballot will be on the IESG agenda of {{ telechat_date }}.
{% endautoescape %}