Repository: ietf-tools/datatracker

Issue:
Conflict review request not changing state for ISE
### Describe the issue

When the ISE clicks the button to request an RFC 5742 conflict review, the document state should change to "In IESG Review".  This isn't happening, and it is a regression.  I had to set the status manually for the last two documents I sent over, draft-pkcs12-gost and draft-makarenko-gost2012-dnssec.

### Code of Conduct

- [X] I agree to follow the [IETF's Code of Conduct](https://github.com/ietf-tools/.github/blob/main/CODE_OF_CONDUCT.md)


Discussion:

Resolving patch:
diff --git a/ietf/doc/views_conflict_review.py b/ietf/doc/views_conflict_review.py
--- a/ietf/doc/views_conflict_review.py
+++ b/ietf/doc/views_conflict_review.py
@@ -99,8 +99,7 @@ def change_state(request, name, option=None):
 
                 if new_state.slug in ["appr-reqnopub-sent", "appr-noprob-sent", "withdraw", "dead"]:
                     doc = review.related_that_doc("conflrev")[0].document
-                    if doc.stream_id == "irtf":
-                        close_review_irtf_state(doc, login)
+                    update_stream_state(doc, login, 'chair-w' if doc.stream_id=='irtf' else 'ise-rev', 'iesg-com')
 
             return redirect('ietf.doc.views_doc.document_main', name=review.name)
     else:
@@ -367,8 +366,7 @@ def approve_conflict_review(request, name):
             c.save()
 
             doc = review.related_that_doc("conflrev")[0].document
-            if doc.stream_id == "irtf":
-                close_review_irtf_state(doc, login)
+            update_stream_state(doc, login, 'chair-w' if doc.stream_id=='irtf' else 'ise-rev', 'iesg-com')
 
             return HttpResponseRedirect(review.get_absolute_url())
 
@@ -503,8 +501,7 @@ def start_review_as_secretariat(request, name):
 
             send_conflict_review_started_email(request, conflict_review)
 
-            if doc_to_review.stream_id == 'irtf':
-                start_review_irtf_state(doc_to_review, login)
+            update_stream_state(doc_to_review, login, 'iesg-rev')
 
             return HttpResponseRedirect(conflict_review.get_absolute_url())
     else: 
@@ -540,8 +537,7 @@ def start_review_as_stream_owner(request, name):
 
             send_conflict_review_started_email(request, conflict_review)
 
-            if doc_to_review.stream_id == 'irtf':
-                start_review_irtf_state(doc_to_review, login)
+            update_stream_state(doc_to_review, login, 'iesg-rev')
 
             return HttpResponseRedirect(conflict_review.get_absolute_url())
     else: 
@@ -558,25 +554,21 @@ def start_review_as_stream_owner(request, name):
                               },
                           )
 
-def start_review_irtf_state(doc, by):
-    prev_state = doc.get_state('draft-stream-irtf')
-    new_state = State.objects.get(type_id='draft-stream-irtf', slug='iesg-rev')
+def update_stream_state(doc, by, state, tag=None):
+    statetype = 'draft-stream-' + doc.stream_id
+    prev_state = doc.get_state(statetype)
+    new_state = State.objects.get(type_id=statetype, slug=state)
+    if tag:
+        prev_tags = set(doc.tags.all())
+        new_tags = set(DocTagName.objects.filter(pk=tag))
 
     if new_state != prev_state:
         doc.set_state(new_state)
         events = []
-        events.append(add_state_change_event(doc, by, prev_state, new_state))
-        doc.save_with_history(events)
-
-def close_review_irtf_state(doc, by):
-    prev_state = doc.get_state("draft-stream-irtf")
-    new_state = State.objects.get(type_id="draft-stream-irtf", slug="chair-w")
-    prev_tags = set(doc.tags.all())
-    new_tags = set(DocTagName.objects.filter(pk="iesg-com"))
-
-    if new_state != prev_state:
-        doc.set_state(new_state)
-        doc.tags.clear()
-        doc.tags.set(new_tags)
-        events = [add_state_change_event(doc, by, prev_state, new_state, prev_tags, new_tags)]
+        if tag:
+            doc.tags.clear()
+            doc.tags.set(new_tags)
+            events.append(add_state_change_event(doc, by, prev_state, new_state, prev_tags, new_tags))
+        else:
+            events.append(add_state_change_event(doc, by, prev_state, new_state))
         doc.save_with_history(events)


Test patch:
diff --git a/ietf/doc/tests_conflict_review.py b/ietf/doc/tests_conflict_review.py
--- a/ietf/doc/tests_conflict_review.py
+++ b/ietf/doc/tests_conflict_review.py
@@ -466,54 +466,78 @@ def setUp(self):
         super().setUp()
         ConflictReviewFactory(name='conflict-review-imaginary-irtf-submission',review_of=IndividualDraftFactory(name='draft-imaginary-irtf-submission',stream_id='irtf'),notify='notifyme@example.net')
 
-class ConflictReviewIrtfStateTests(TestCase):
+class ConflictReviewStreamStateTests(TestCase):
 
-    def start_review(self, role, kwargs=None):
-        doc = RgDraftFactory()
+    def start_review(self, stream, role, kwargs=None):
+        doc = RgDraftFactory() if stream=='irtf' else IndividualDraftFactory(stream=StreamName.objects.get(slug='ise'))
         url = urlreverse('ietf.doc.views_conflict_review.start_review', kwargs=dict(name=doc.name))
         login_testing_unauthorized(self, role, url)
-
         r = self.client.post(url, kwargs)
         self.assertEqual(r.status_code, 302)
-        self.assertEqual(doc.get_state('draft-stream-irtf').slug, 'iesg-rev')
+        self.assertEqual(doc.get_state('draft-stream-'+stream).slug, 'iesg-rev')
 
-    def test_start_review_as_secretary(self):
+    def test_start_irtf_review_as_secretary(self):
         ad_strpk = str(Person.objects.get(name='Areað Irector').pk)
         state_strpk = str(State.objects.get(used=True, slug='needshep', type__slug='conflrev').pk)
-        self.start_review('secretary', kwargs=dict(ad=ad_strpk, create_in_state=state_strpk))
+        self.start_review('irtf', 'secretary', kwargs=dict(ad=ad_strpk, create_in_state=state_strpk))
 
-    def test_start_review_as_stream_owner(self):
-        self.start_review('irtf-chair')
+    def test_start_ise_review_as_secretary(self):
+        ad_strpk = str(Person.objects.get(name='Areað Irector').pk)
+        state_strpk = str(State.objects.get(used=True, slug='needshep', type__slug='conflrev').pk)
+        self.start_review('ise', 'secretary', kwargs=dict(ad=ad_strpk, create_in_state=state_strpk))
 
-    def close_review(self, close_type, role):
-        doc = RgDraftFactory()
+    def test_start_irtf_review_as_stream_owner(self):
+        self.start_review('irtf', 'irtf-chair')
+
+    def test_start_ise_review_as_stream_owner(self):
+        self.start_review('ise', 'ise-chair')
+
+    def close_review(self, close_type, stream, role):
+        doc = RgDraftFactory() if stream=='irtf' else IndividualDraftFactory(stream=StreamName.objects.get(slug='ise'))
         review = ConflictReviewFactory(review_of=doc)
         url = urlreverse('ietf.doc.views_conflict_review.change_state', kwargs=dict(name=review.name))
         login_testing_unauthorized(self, role, url)
-
         strpk = str(State.objects.get(used=True, slug=close_type, type__slug='conflrev').pk)
         r = self.client.post(url, dict(review_state=strpk))
         self.assertEqual(r.status_code, 302)
-        self.assertEqual(doc.get_state('draft-stream-irtf').slug, 'chair-w')
+        self.assertEqual(doc.get_state('draft-stream-'+stream).slug, 'chair-w' if stream=='irtf' else 'ise-rev')
         self.assertIn(DocTagName.objects.get(pk='iesg-com'), doc.tags.all())
 
-    def test_close_review_reqnopub_as_secretary(self):
-        self.close_review('appr-reqnopub-sent', 'secretary')
+    def test_close_irtf_review_reqnopub_as_secretary(self):
+        self.close_review('appr-reqnopub-sent', 'irtf', 'secretary')
+
+    def test_close_ise_review_reqnopub_as_secretary(self):
+        self.close_review('appr-reqnopub-sent', 'ise', 'secretary')
+
+    def test_close_irtf_review_noprob_as_secretary(self):
+        self.close_review('appr-noprob-sent', 'irtf', 'secretary')
+
+    def test_close_ise_review_noprob_as_secretary(self):
+        self.close_review('appr-noprob-sent', 'ise', 'secretary')
+
+    def test_close_irtf_review_withdraw_as_secretary(self):
+        self.close_review('withdraw', 'irtf', 'secretary')
+
+    def test_close_ise_review_withdraw_as_secretary(self):
+        self.close_review('withdraw', 'ise', 'secretary')
+
+    def test_close_irtf_review_dead_as_secretary(self):
+        self.close_review('dead', 'irtf', 'secretary')
 
-    def test_close_review_noprob_as_secretary(self):
-        self.close_review('appr-noprob-sent', 'secretary')
+    def test_close_ise_review_dead_as_secretary(self):
+        self.close_review('dead', 'ise', 'secretary')
 
-    def test_close_review_withdraw_as_secretary(self):
-        self.close_review('withdraw', 'secretary')
+    def test_close_irtf_review_withdraw_as_ad(self):
+        self.close_review('withdraw', 'irtf', 'ad')
 
-    def test_close_review_dead_as_secretary(self):
-        self.close_review('dead', 'secretary')
+    def test_close_ise_review_withdraw_as_ad(self):
+        self.close_review('withdraw', 'ise', 'ad')
 
-    def test_close_review_withdraw_as_ad(self):
-        self.close_review('withdraw', 'ad')
+    def test_close_irtf_review_dead_as_ad(self):
+        self.close_review('dead', 'irtf', 'ad')
 
-    def test_close_review_dead_as_ad(self):
-        self.close_review('dead', 'ad')
+    def test_close_ise_review_dead_as_ad(self):
+        self.close_review('dead', 'ise', 'ad')
 
     def test_approve_review(self):
         doc = RgDraftFactory()