Skip to content

Commit

Permalink
fix: check correct state machine when clearing status change ballots (#…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
rjsparks authored Jul 15, 2024
1 parent c9dab33 commit 17e0f57
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 2 deletions.
7 changes: 6 additions & 1 deletion ietf/doc/tests_ballot.py
Original file line number Diff line number Diff line change
Expand Up @@ -806,7 +806,7 @@ def test_clear_ballot(self):
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))
url = urlreverse('ietf.doc.views_ballot.clear_ballot', kwargs=dict(name=draft.name,ballot_type_slug="approve"))
login_testing_unauthorized(self, "secretary", url)
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
Expand All @@ -816,6 +816,11 @@ def test_clear_ballot(self):
self.assertIsNotNone(ballot)
self.assertEqual(ballot.ballotpositiondocevent_set.count(),0)
self.assertNotEqual(old_ballot_id, ballot.id)
# It's not valid to clear a ballot of a type where there's no matching state
url = urlreverse('ietf.doc.views_ballot.clear_ballot', kwargs=dict(name=draft.name,ballot_type_slug="statchg"))
r = self.client.post(url,{})
self.assertEqual(r.status_code, 404)


def test_ballot_downref_approve(self):
ad = Person.objects.get(name="Areað Irector")
Expand Down
40 changes: 40 additions & 0 deletions ietf/doc/tests_status_change.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,47 @@ def verify_relations(doc,target_name,status):
verify_relations(doc,'rfc9998','tobcp' )
verify_relations(doc,'rfc14' ,'tohist')
self.assertTrue(doc.latest_event(DocEvent,type="added_comment").desc.startswith('Affected RFC list changed.'))

def test_clear_ballot(self):
doc = Document.objects.get(name='status-change-imaginary-mid-review')
url = urlreverse('ietf.doc.views_ballot.clear_ballot',kwargs=dict(name=doc.name, ballot_type_slug="statchg"))
login_testing_unauthorized(self, "secretary", url)

# Some additional setup
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9998'),relationship_id='tohist')
create_ballot_if_not_open(None, doc, Person.objects.get(user__username="secretary"), "statchg")
doc.set_state(State.objects.get(slug='iesgeval',type='statchg'))
old_ballot = doc.ballot_open("statchg")
self.assertIsNotNone(old_ballot)

r = self.client.post(url, dict())
self.assertEqual(r.status_code,302)
new_ballot = doc.ballot_open("statchg")
self.assertIsNotNone(new_ballot)
self.assertNotEqual(new_ballot, old_ballot)
self.assertEqual(doc.get_state_slug("statchg"),"iesgeval")

def test_clear_deferred_ballot(self):
doc = Document.objects.get(name='status-change-imaginary-mid-review')
url = urlreverse('ietf.doc.views_ballot.clear_ballot',kwargs=dict(name=doc.name, ballot_type_slug="statchg"))
login_testing_unauthorized(self, "secretary", url)

# Some additional setup
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9999'),relationship_id='tois')
doc.relateddocument_set.create(target=Document.objects.get(name='rfc9998'),relationship_id='tohist')
create_ballot_if_not_open(None, doc, Person.objects.get(user__username="secretary"), "statchg")
doc.set_state(State.objects.get(slug='defer',type='statchg'))
old_ballot = doc.ballot_open("statchg")
self.assertIsNotNone(old_ballot)

r = self.client.post(url, dict())
self.assertEqual(r.status_code,302)
new_ballot = doc.ballot_open("statchg")
self.assertIsNotNone(new_ballot)
self.assertNotEqual(new_ballot, old_ballot)
self.assertEqual(doc.get_state_slug("statchg"),"iesgeval")

def setUp(self):
super().setUp()
IndividualRfcFactory(rfc_number=14,std_level_id='unkn') # draft was never issued
Expand Down
13 changes: 12 additions & 1 deletion ietf/doc/views_ballot.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,11 +399,22 @@ def send_ballot_comment(request, name, ballot_id):
def clear_ballot(request, name, ballot_type_slug):
"""Clear all positions and discusses on every open ballot for a document."""
doc = get_object_or_404(Document, name=name)
# If there's no appropriate ballot type state, clearing would be an invalid action.
# This will need to be updated if we ever allow defering IRTF ballots
if ballot_type_slug == "approve":
state_machine = "draft-iesg"
elif ballot_type_slug in ["statchg","conflrev"]:
state_machine = ballot_type_slug
else:
state_machine = None
state_slug = state_machine and doc.get_state_slug(state_machine)
if state_machine is None or state_slug is None:
raise Http404
if request.method == 'POST':
by = request.user.person
if close_ballot(doc, by, ballot_type_slug):
create_ballot_if_not_open(request, doc, by, ballot_type_slug)
if doc.get_state('draft-iesg').slug == 'defer':
if state_slug == "defer":
do_undefer_ballot(request,doc)
return redirect("ietf.doc.views_doc.document_main", name=doc.name)

Expand Down

0 comments on commit 17e0f57

Please sign in to comment.