Skip to content

Commit 17e0f57

Browse files
authored
fix: check correct state machine when clearing status change ballots (#7684)
* fix: check correct state machine when clearing status change ballots Fixes #7335 * fix: Improve ballot clearing tests * fix: look at the right state machines for defer state for a ballot * fix: also do the right thing with conflrev defers
1 parent c9dab33 commit 17e0f57

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

ietf/doc/tests_ballot.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,7 @@ def test_clear_ballot(self):
806806
ballot = create_ballot_if_not_open(None, draft, ad, 'approve')
807807
old_ballot_id = ballot.id
808808
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="iesg-eva"))
809-
url = urlreverse('ietf.doc.views_ballot.clear_ballot', kwargs=dict(name=draft.name,ballot_type_slug=draft.ballot_open('approve').ballot_type.slug))
809+
url = urlreverse('ietf.doc.views_ballot.clear_ballot', kwargs=dict(name=draft.name,ballot_type_slug="approve"))
810810
login_testing_unauthorized(self, "secretary", url)
811811
r = self.client.get(url)
812812
self.assertEqual(r.status_code, 200)
@@ -816,6 +816,11 @@ def test_clear_ballot(self):
816816
self.assertIsNotNone(ballot)
817817
self.assertEqual(ballot.ballotpositiondocevent_set.count(),0)
818818
self.assertNotEqual(old_ballot_id, ballot.id)
819+
# It's not valid to clear a ballot of a type where there's no matching state
820+
url = urlreverse('ietf.doc.views_ballot.clear_ballot', kwargs=dict(name=draft.name,ballot_type_slug="statchg"))
821+
r = self.client.post(url,{})
822+
self.assertEqual(r.status_code, 404)
823+
819824

820825
def test_ballot_downref_approve(self):
821826
ad = Person.objects.get(name="Areað Irector")

ietf/doc/tests_status_change.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,47 @@ def verify_relations(doc,target_name,status):
484484
verify_relations(doc,'rfc9998','tobcp' )
485485
verify_relations(doc,'rfc14' ,'tohist')
486486
self.assertTrue(doc.latest_event(DocEvent,type="added_comment").desc.startswith('Affected RFC list changed.'))
487+
488+
def test_clear_ballot(self):
489+
doc = Document.objects.get(name='status-change-imaginary-mid-review')
490+
url = urlreverse('ietf.doc.views_ballot.clear_ballot',kwargs=dict(name=doc.name, ballot_type_slug="statchg"))
491+
login_testing_unauthorized(self, "secretary", url)
492+
493+
# Some additional setup
494+
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9999'),relationship_id='tois')
495+
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9998'),relationship_id='tohist')
496+
create_ballot_if_not_open(None, doc, Person.objects.get(user__username="secretary"), "statchg")
497+
doc.set_state(State.objects.get(slug='iesgeval',type='statchg'))
498+
old_ballot = doc.ballot_open("statchg")
499+
self.assertIsNotNone(old_ballot)
500+
501+
r = self.client.post(url, dict())
502+
self.assertEqual(r.status_code,302)
503+
new_ballot = doc.ballot_open("statchg")
504+
self.assertIsNotNone(new_ballot)
505+
self.assertNotEqual(new_ballot, old_ballot)
506+
self.assertEqual(doc.get_state_slug("statchg"),"iesgeval")
507+
508+
def test_clear_deferred_ballot(self):
509+
doc = Document.objects.get(name='status-change-imaginary-mid-review')
510+
url = urlreverse('ietf.doc.views_ballot.clear_ballot',kwargs=dict(name=doc.name, ballot_type_slug="statchg"))
511+
login_testing_unauthorized(self, "secretary", url)
512+
513+
# Some additional setup
514+
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9999'),relationship_id='tois')
515+
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9998'),relationship_id='tohist')
516+
create_ballot_if_not_open(None, doc, Person.objects.get(user__username="secretary"), "statchg")
517+
doc.set_state(State.objects.get(slug='defer',type='statchg'))
518+
old_ballot = doc.ballot_open("statchg")
519+
self.assertIsNotNone(old_ballot)
487520

521+
r = self.client.post(url, dict())
522+
self.assertEqual(r.status_code,302)
523+
new_ballot = doc.ballot_open("statchg")
524+
self.assertIsNotNone(new_ballot)
525+
self.assertNotEqual(new_ballot, old_ballot)
526+
self.assertEqual(doc.get_state_slug("statchg"),"iesgeval")
527+
488528
def setUp(self):
489529
super().setUp()
490530
IndividualRfcFactory(rfc_number=14,std_level_id='unkn') # draft was never issued

ietf/doc/views_ballot.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,11 +399,22 @@ def send_ballot_comment(request, name, ballot_id):
399399
def clear_ballot(request, name, ballot_type_slug):
400400
"""Clear all positions and discusses on every open ballot for a document."""
401401
doc = get_object_or_404(Document, name=name)
402+
# If there's no appropriate ballot type state, clearing would be an invalid action.
403+
# This will need to be updated if we ever allow defering IRTF ballots
404+
if ballot_type_slug == "approve":
405+
state_machine = "draft-iesg"
406+
elif ballot_type_slug in ["statchg","conflrev"]:
407+
state_machine = ballot_type_slug
408+
else:
409+
state_machine = None
410+
state_slug = state_machine and doc.get_state_slug(state_machine)
411+
if state_machine is None or state_slug is None:
412+
raise Http404
402413
if request.method == 'POST':
403414
by = request.user.person
404415
if close_ballot(doc, by, ballot_type_slug):
405416
create_ballot_if_not_open(request, doc, by, ballot_type_slug)
406-
if doc.get_state('draft-iesg').slug == 'defer':
417+
if state_slug == "defer":
407418
do_undefer_ballot(request,doc)
408419
return redirect("ietf.doc.views_doc.document_main", name=doc.name)
409420

0 commit comments

Comments
 (0)