Skip to content

Commit f19d104

Browse files
authored
feat: Update IRTF state when entering/exiting IETF conflict review (ietf-tools#6424)
* feat: Update IRTF state when entering/exiting IETF conflict review (ietf-tools#3469) * fix: Update IRTF state in approve_conflict_review() as well * chore: Add "new_state != prev_state" guard
1 parent 5e0d1be commit f19d104

2 files changed

Lines changed: 104 additions & 4 deletions

File tree

ietf/doc/tests_conflict_review.py

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright The IETF Trust 2012-2020, All Rights Reserved
1+
# Copyright The IETF Trust 2012-2023, All Rights Reserved
22
# -*- coding: utf-8 -*-
33

44

@@ -13,8 +13,8 @@
1313

1414
import debug # pyflakes:ignore
1515

16-
from ietf.doc.factories import IndividualDraftFactory, ConflictReviewFactory
17-
from ietf.doc.models import Document, DocEvent, NewRevisionDocEvent, BallotPositionDocEvent, TelechatDocEvent, State
16+
from ietf.doc.factories import IndividualDraftFactory, ConflictReviewFactory, RgDraftFactory
17+
from ietf.doc.models import Document, DocEvent, NewRevisionDocEvent, BallotPositionDocEvent, TelechatDocEvent, State, DocTagName
1818
from ietf.doc.utils import create_ballot_if_not_open
1919
from ietf.doc.views_conflict_review import default_approval_text
2020
from ietf.group.models import Person
@@ -450,3 +450,65 @@ def test_subsequent_submission(self):
450450
def setUp(self):
451451
super().setUp()
452452
ConflictReviewFactory(name='conflict-review-imaginary-irtf-submission',review_of=IndividualDraftFactory(name='draft-imaginary-irtf-submission',stream_id='irtf'),notify='notifyme@example.net')
453+
454+
class ConflictReviewIrtfStateTests(TestCase):
455+
456+
def start_review(self, role, kwargs=None):
457+
doc = RgDraftFactory()
458+
url = urlreverse('ietf.doc.views_conflict_review.start_review', kwargs=dict(name=doc.name))
459+
login_testing_unauthorized(self, role, url)
460+
461+
r = self.client.post(url, kwargs)
462+
self.assertEqual(r.status_code, 302)
463+
self.assertEqual(doc.get_state('draft-stream-irtf').slug, 'iesg-rev')
464+
465+
def test_start_review_as_secretary(self):
466+
ad_strpk = str(Person.objects.get(name='Areað Irector').pk)
467+
state_strpk = str(State.objects.get(used=True, slug='needshep', type__slug='conflrev').pk)
468+
self.start_review('secretary', kwargs=dict(ad=ad_strpk, create_in_state=state_strpk))
469+
470+
def test_start_review_as_stream_owner(self):
471+
self.start_review('irtf-chair')
472+
473+
def close_review(self, close_type, role):
474+
doc = RgDraftFactory()
475+
review = ConflictReviewFactory(review_of=doc)
476+
url = urlreverse('ietf.doc.views_conflict_review.change_state', kwargs=dict(name=review.name))
477+
login_testing_unauthorized(self, role, url)
478+
479+
strpk = str(State.objects.get(used=True, slug=close_type, type__slug='conflrev').pk)
480+
r = self.client.post(url, dict(review_state=strpk))
481+
self.assertEqual(r.status_code, 302)
482+
self.assertEqual(doc.get_state('draft-stream-irtf').slug, 'chair-w')
483+
self.assertIn(DocTagName.objects.get(pk='iesg-com'), doc.tags.all())
484+
485+
def test_close_review_reqnopub_as_secretary(self):
486+
self.close_review('appr-reqnopub-sent', 'secretary')
487+
488+
def test_close_review_noprob_as_secretary(self):
489+
self.close_review('appr-noprob-sent', 'secretary')
490+
491+
def test_close_review_withdraw_as_secretary(self):
492+
self.close_review('withdraw', 'secretary')
493+
494+
def test_close_review_dead_as_secretary(self):
495+
self.close_review('dead', 'secretary')
496+
497+
def test_close_review_withdraw_as_ad(self):
498+
self.close_review('withdraw', 'ad')
499+
500+
def test_close_review_dead_as_ad(self):
501+
self.close_review('dead', 'ad')
502+
503+
def test_approve_review(self):
504+
doc = RgDraftFactory()
505+
review = ConflictReviewFactory(review_of=doc)
506+
review.set_state(State.objects.get(used=True, slug='appr-noprob-pend', type='conflrev'))
507+
508+
url = urlreverse('ietf.doc.views_conflict_review.approve_conflict_review', kwargs=dict(name=review.name))
509+
login_testing_unauthorized(self, 'secretary', url)
510+
511+
r = self.client.post(url, dict(announcement_text=default_approval_text(review)))
512+
self.assertEqual(r.status_code, 302)
513+
self.assertEqual(doc.get_state('draft-stream-irtf').slug, 'chair-w')
514+
self.assertIn(DocTagName.objects.get(pk='iesg-com'), doc.tags.all())

ietf/doc/views_conflict_review.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright The IETF Trust 2012-2020, All Rights Reserved
1+
# Copyright The IETF Trust 2012-2023, All Rights Reserved
22
# -*- coding: utf-8 -*-
33

44

@@ -25,6 +25,7 @@
2525
from ietf.group.models import Role, Group
2626
from ietf.iesg.models import TelechatDate
2727
from ietf.ietfauth.utils import has_role, role_required, is_authorized_in_doc_stream
28+
from ietf.name.models import DocTagName
2829
from ietf.person.models import Person
2930
from ietf.utils import log
3031
from ietf.utils.mail import send_mail_preformatted
@@ -90,6 +91,10 @@ def change_state(request, name, option=None):
9091
review,
9192
ok_to_publish)
9293

94+
if new_state.slug in ["appr-reqnopub-sent", "appr-noprob-sent", "withdraw", "dead"]:
95+
doc = review.related_that_doc("conflrev")[0].document
96+
if doc.stream_id == "irtf":
97+
close_review_irtf_state(doc, login)
9398

9499
return redirect('ietf.doc.views_doc.document_main', name=review.name)
95100
else:
@@ -355,6 +360,10 @@ def approve_conflict_review(request, name):
355360
c.desc = "The following approval message was sent\n"+form.cleaned_data['announcement_text']
356361
c.save()
357362

363+
doc = review.related_that_doc("conflrev")[0].document
364+
if doc.stream_id == "irtf":
365+
close_review_irtf_state(doc, login)
366+
358367
return HttpResponseRedirect(review.get_absolute_url())
359368

360369
else:
@@ -488,6 +497,9 @@ def start_review_as_secretariat(request, name):
488497

489498
send_conflict_review_started_email(request, conflict_review)
490499

500+
if doc_to_review.stream_id == 'irtf':
501+
start_review_irtf_state(doc_to_review, login)
502+
491503
return HttpResponseRedirect(conflict_review.get_absolute_url())
492504
else:
493505
notify_addresses = build_notify_addresses(doc_to_review)
@@ -522,6 +534,9 @@ def start_review_as_stream_owner(request, name):
522534

523535
send_conflict_review_started_email(request, conflict_review)
524536

537+
if doc_to_review.stream_id == 'irtf':
538+
start_review_irtf_state(doc_to_review, login)
539+
525540
return HttpResponseRedirect(conflict_review.get_absolute_url())
526541
else:
527542
notify_addresses = build_notify_addresses(doc_to_review)
@@ -536,3 +551,26 @@ def start_review_as_stream_owner(request, name):
536551
'doc_to_review': doc_to_review,
537552
},
538553
)
554+
555+
def start_review_irtf_state(doc, by):
556+
prev_state = doc.get_state('draft-stream-irtf')
557+
new_state = State.objects.get(type_id='draft-stream-irtf', slug='iesg-rev')
558+
559+
if new_state != prev_state:
560+
doc.set_state(new_state)
561+
events = []
562+
events.append(add_state_change_event(doc, by, prev_state, new_state))
563+
doc.save_with_history(events)
564+
565+
def close_review_irtf_state(doc, by):
566+
prev_state = doc.get_state("draft-stream-irtf")
567+
new_state = State.objects.get(type_id="draft-stream-irtf", slug="chair-w")
568+
prev_tags = set(doc.tags.all())
569+
new_tags = set(DocTagName.objects.filter(pk="iesg-com"))
570+
571+
if new_state != prev_state:
572+
doc.set_state(new_state)
573+
doc.tags.clear()
574+
doc.tags.set(new_tags)
575+
events = [add_state_change_event(doc, by, prev_state, new_state, prev_tags, new_tags)]
576+
doc.save_with_history(events)

0 commit comments

Comments
 (0)