Merged in [15084] from rjsparks@nostrum.com:

Corrected the implementation of clear_ballot. Added a test for it. Restored functionality to ballot popups that was missing because a template variable was not passed in.
 - Legacy-Id: 15092
Note: SVN reference [15084] has been migrated to Git commit ee346edaba
This commit is contained in:
Henrik Levkowetz 2018-04-26 13:41:22 +00:00
commit 198c003b6a
8 changed files with 29 additions and 10 deletions

View file

@ -644,6 +644,23 @@ class ApproveBallotTests(TestCase):
self.assertEqual(len(outbox), mailbox_before + 1) self.assertEqual(len(outbox), mailbox_before + 1)
self.assertTrue("NOT be published" in str(outbox[-1])) self.assertTrue("NOT be published" in str(outbox[-1]))
def test_clear_ballot(self):
draft = make_test_data()
ad = Person.objects.get(user__username="ad")
ballot = create_ballot_if_not_open(None, draft, ad, 'approve')
old_ballot_id = ballot.id
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva"))
url = urlreverse('ietf.doc.views_ballot.clear_ballot', kwargs=dict(name=draft.name,ballot_type_slug=draft.ballot_open('approve').ballot_type.slug))
login_testing_unauthorized(self, "secretary", url)
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
r = self.client.post(url,{})
self.assertEqual(r.status_code, 302)
ballot = draft.ballot_open('approve')
self.assertIsNotNone(ballot)
self.assertEqual(ballot.ballotpositiondocevent_set.count(),0)
self.assertNotEqual(old_ballot_id, ballot.id)
class MakeLastCallTests(TestCase): class MakeLastCallTests(TestCase):
def test_make_last_call(self): def test_make_last_call(self):
draft = make_test_data() draft = make_test_data()

View file

@ -108,7 +108,7 @@ urlpatterns = [
url(r'^%(name)s/edit/adopt/$' % settings.URL_REGEXPS, views_draft.adopt_draft), url(r'^%(name)s/edit/adopt/$' % settings.URL_REGEXPS, views_draft.adopt_draft),
url(r'^%(name)s/edit/state/(?P<state_type>draft-stream-[a-z]+)/$' % settings.URL_REGEXPS, views_draft.change_stream_state), url(r'^%(name)s/edit/state/(?P<state_type>draft-stream-[a-z]+)/$' % settings.URL_REGEXPS, views_draft.change_stream_state),
url(r'^%(name)s/edit/clearballot/$' % settings.URL_REGEXPS, views_ballot.clear_ballot), url(r'^%(name)s/edit/clearballot/(?P<ballot_type_slug>[\w-]+)/$' % settings.URL_REGEXPS, views_ballot.clear_ballot),
url(r'^%(name)s/edit/deferballot/$' % settings.URL_REGEXPS, views_ballot.defer_ballot), url(r'^%(name)s/edit/deferballot/$' % settings.URL_REGEXPS, views_ballot.defer_ballot),
url(r'^%(name)s/edit/undeferballot/$' % settings.URL_REGEXPS, views_ballot.undefer_ballot), url(r'^%(name)s/edit/undeferballot/$' % settings.URL_REGEXPS, views_ballot.undefer_ballot),
url(r'^%(name)s/edit/lastcalltext/$' % settings.URL_REGEXPS, views_ballot.lastcalltext), url(r'^%(name)s/edit/lastcalltext/$' % settings.URL_REGEXPS, views_ballot.lastcalltext),

View file

@ -16,7 +16,7 @@ from django.views.decorators.csrf import csrf_exempt
import debug # pyflakes:ignore import debug # pyflakes:ignore
from ietf.doc.models import ( Document, State, DocEvent, BallotDocEvent, BallotPositionDocEvent, from ietf.doc.models import ( Document, State, DocEvent, BallotDocEvent, BallotPositionDocEvent,
BallotType, LastCallDocEvent, WriteupDocEvent, IESG_SUBSTATE_TAGS ) LastCallDocEvent, WriteupDocEvent, IESG_SUBSTATE_TAGS )
from ietf.doc.utils import ( add_state_change_event, close_ballot, close_open_ballots, from ietf.doc.utils import ( add_state_change_event, close_ballot, close_open_ballots,
create_ballot_if_not_open, update_telechat ) create_ballot_if_not_open, update_telechat )
from ietf.doc.mails import ( email_ballot_deferred, email_ballot_undeferred, from ietf.doc.mails import ( email_ballot_deferred, email_ballot_undeferred,
@ -381,14 +381,13 @@ def send_ballot_comment(request, name, ballot_id):
)) ))
@role_required('Area Director','Secretariat') @role_required('Area Director','Secretariat')
def clear_ballot(request, name): def clear_ballot(request, name, ballot_type_slug):
"""Clear all positions and discusses on every open ballot for a document.""" """Clear all positions and discusses on every open ballot for a document."""
doc = get_object_or_404(Document, name=name) doc = get_object_or_404(Document, name=name)
if request.method == 'POST': if request.method == 'POST':
by = request.user.person by = request.user.person
for t in BallotType.objects.filter(doc_type=doc.type_id): if close_ballot(doc, by, ballot_type_slug):
close_ballot(doc, by, t.slug) create_ballot_if_not_open(request, doc, by, ballot_type_slug)
create_ballot_if_not_open(request, doc, by, t.slug)
if doc.get_state('draft-iesg').slug == 'defer': if doc.get_state('draft-iesg').slug == 'defer':
do_undefer_ballot(request,doc) do_undefer_ballot(request,doc)
return redirect("ietf.doc.views_doc.document_main", name=doc.name) return redirect("ietf.doc.views_doc.document_main", name=doc.name)

View file

@ -965,10 +965,13 @@ def document_ballot(request, name, ballot_id=None):
def ballot_popup(request, name, ballot_id): def ballot_popup(request, name, ballot_id):
doc = get_object_or_404(Document, docalias__name=name) doc = get_object_or_404(Document, docalias__name=name)
c = document_ballot_content(request, doc, ballot_id=ballot_id, editable=False) c = document_ballot_content(request, doc, ballot_id=ballot_id, editable=False)
ballot = get_object_or_404(BallotDocEvent,id=ballot_id)
return render(request, "doc/ballot_popup.html", return render(request, "doc/ballot_popup.html",
dict(doc=doc, dict(doc=doc,
ballot_content=c, ballot_content=c,
ballot_id=ballot_id, ballot_id=ballot_id,
ballot_type_slug=ballot.ballot_type.slug,
editable=True,
)) ))

View file

@ -375,7 +375,7 @@ def make_nomineeposition_for_newperson(nomcom, candidate_name, candidate_email,
email = Email.objects.create(address=candidate_email) email = Email.objects.create(address=candidate_email)
person = Person.objects.create(name=candidate_name, person = Person.objects.create(name=candidate_name,
ascii=unidecode_name(candidate_name), ascii=unidecode_name(candidate_name),
address=candidate_email) )
email.person = person email.person = person
email.save() email.save()

View file

@ -38,7 +38,7 @@
{% endif %} {% endif %}
{% if user|has_role:"Secretariat" %} {% if user|has_role:"Secretariat" %}
<a class="btn btn-danger" href="{% url 'ietf.doc.views_ballot.clear_ballot' name=doc.name %}">Clear ballot</a> <a class="btn btn-danger" href="{% url 'ietf.doc.views_ballot.clear_ballot' name=doc.name ballot_type_slug=ballot_type_slug %}">Clear ballot</a>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endif %} {% endif %}

View file

@ -67,7 +67,7 @@
{% endif %} {% endif %}
{% if user|has_role:"Area Director,Secretariat" %} {% if user|has_role:"Area Director,Secretariat" %}
<a class="btn btn-danger" href="{% url 'ietf.doc.views_ballot.clear_ballot' name=doc.name %}">Clear ballot</a> <a class="btn btn-danger" href="{% url 'ietf.doc.views_ballot.clear_ballot' name=doc.name ballot_type_slug=ballot.ballot_type.slug%}">Clear ballot</a>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endif %} {% endif %}

View file

@ -60,7 +60,7 @@ def make_immutable_base_data():
date4 = TelechatDate.objects.create(date=t + datetime.timedelta(days=14 * 3)).date # pyflakes:ignore date4 = TelechatDate.objects.create(date=t + datetime.timedelta(days=14 * 3)).date # pyflakes:ignore
# system # system
system_person = Person.objects.create(name="(System)", ascii="(System)", address="") system_person = Person.objects.create(name="(System)", ascii="(System)")
Email.objects.create(address="", person=system_person) Email.objects.create(address="", person=system_person)
# high-level groups # high-level groups