Repository: ietf-tools/datatracker

Issue:
Multiple (duplicate) DocEvents being created on Review Assignment
Look at, e.g., https://datatracker.ietf.org/doc/draft-ietf-sfc-oam-packet/history/
```
>>> DocEvent.objects.filter(desc='Request for Last Call review by ARTART is assigned to Barry Leiba',doc__name='draft-ietf-sfc-oam-packet')
<QuerySet [
<DocEvent: draft-ietf-sfc-oam-packet assigned review request by Barry Leiba at 2022-11-08 01:15:55+00:00>, 
<DocEvent: draft-ietf-sfc-oam-packet assigned review request by Barry Leiba at 2022-11-08 01:15:55+00:00>
]>
```


Discussion:
This reflects that both a `ReviewRequestDocEvent` and a `ReviewAssignmentDocEvent` are created:
```
>>> DocEvent.objects.filter(desc='Request for Last Call review by ARTART is assigned to Barry Leiba', doc__name='draft-ietf-sfc-oam-packet').values_list('pk', flat=True)
<QuerySet [890515, 890514]>
>>> ReviewRequestDocEvent.objects.filter(desc='Request for Last Call review by ARTART is assigned to Barry Leiba', doc__name='draft-ietf-sfc-oam-packet').values_list('pk', flat=True)
<QuerySet [890514]>
>>> ReviewAssignmentDocEvent.objects.filter(desc='Request for Last Call review by ARTART is assigned to Barry Leiba', doc__name='draft-ietf-sfc-oam-packet').values_list('pk', flat=True)
<QuerySet [890515]>
```

I'm not sure what the right thing to do is here. Maybe filter events with identical descriptions out of the history?
Is having a ReviewRequestDocEvent dropped at the point that a ReviewAssignment is made the right thing to do? I suspect it isn't and it's an artifact of before we explicitly split out ReviewAssignments.
To be explicit - would any expectations be broken if we deleted the ReviewRequestDocEvents that have "is assigned" in their desc, and change the code to quit making new ones?
Looking at the history, when `ReviewAssignment` was added, the places where `ReviewRequestDocEvent` records were created for assigning and closing review requests were duplicated. This happens in a migraiton (`0010_populate_review_assignments.py`) as well as for new activity.

I'm not finding much that looks like it depends on there being the duplicates, so I think it'd be ok. Checked and there is always a `ReviewAssignmentDocEvent` with the same description within a minute of every `ReviewRequestDocEvent` and vice versa, with one exception:
```
ReviewRequestDocEvent.objects.get(doc__name='draft-ietf-sidr-slurm', time='2018-02-19 08:16:27+00').desc
'Request for Last Call review by OPSDIR is assigned to (None)'
```
Not sure what's up with that one.

I'm a little surprised that I had to allow for a full minute of skew to match up identical events between the two classes, but assuming that level of precision is ok, we can recreate the events we remove if it turns out they were needed.

Resolving patch:
diff --git a/ietf/review/utils.py b/ietf/review/utils.py
--- a/ietf/review/utils.py
+++ b/ietf/review/utils.py
@@ -398,15 +398,6 @@ def assign_review_request_to_reviewer(request, review_req, reviewer, add_skip=Fa
             review_req.team.acronym.upper(),
             reviewer.person if reviewer else "(None)")
     update_change_reason(assignment, descr)
-    ReviewRequestDocEvent.objects.create(
-        type="assigned_review_request",
-        doc=review_req.doc,
-        rev=review_req.doc.rev,
-        by=request.user.person,
-        desc=descr,
-        review_request=review_req,
-        state_id='assigned',
-    )
 
     ReviewAssignmentDocEvent.objects.create(
         type="assigned_review_request",
@@ -416,7 +407,7 @@ def assign_review_request_to_reviewer(request, review_req, reviewer, add_skip=Fa
         desc="Request for {} review by {} is assigned to {}".format(
             review_req.type.name,
             review_req.team.acronym.upper(),
-            reviewer.person,
+            reviewer.person if reviewer else "(None)",
         ),
         review_assignment=assignment,
         state_id='assigned',


Test patch:
diff --git a/ietf/doc/tests_review.py b/ietf/doc/tests_review.py
--- a/ietf/doc/tests_review.py
+++ b/ietf/doc/tests_review.py
@@ -345,6 +345,16 @@ def test_assign_reviewer(self):
         self.assertIn("This team has completed other reviews", message)
         self.assertIn("{} -01 Serious Issues".format(reviewer_email.person.ascii), message)
 
+        # check events
+        assignment_events = assignment.reviewassignmentdocevent_set.all()
+        self.assertEqual(assignment_events.count(), 1)
+        e = assignment_events.first()
+        self.assertEqual(e.type, 'assigned_review_request')
+        self.assertIn('is assigned', e.desc)
+        self.assertEqual(e.doc, doc)
+        request_events = review_req.reviewrequestdocevent_set.all()
+        self.assertEqual(request_events.count(), 0)
+
     def test_previously_reviewed_replaced_doc(self):
         review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review", list_email="reviewteam@ietf.org", parent=Group.objects.get(acronym="farfut"))
         rev_role = RoleFactory(group=review_team,person__user__username='reviewer',person__user__email='reviewer@example.com',person__name='Some Reviewer',name_id='reviewer')