feat: add "add comment" feature to the review requests. (#6603)

This commit is contained in:
Tero Kivinen 2023-11-05 03:29:25 -05:00 committed by GitHub
parent d5e4ea8183
commit 53d0014826
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 94 additions and 2 deletions

View file

@ -9,6 +9,7 @@ urlpatterns = [
url(r'^(?P<request_id>[0-9]+)/$', views_review.review_request),
url(r'^(?P<request_id>[0-9]+)/login/$', views_review.review_request_forced_login),
url(r'^(?P<request_id>[0-9]+)/close/$', views_review.close_request),
url(r'^(?P<request_id>[0-9]+)/addrequestcomment/$', views_review.add_request_comment),
url(r'^(?P<request_id>[0-9]+)/assignreviewer/$', views_review.assign_reviewer),
url(r'^(?P<assignment_id>[0-9]+)/rejectreviewerassignment/$', views_review.reject_reviewer_assignment),
url(r'^(?P<assignment_id>[0-9]+)/complete/$', views_review.complete_review),

View file

@ -219,6 +219,8 @@ def review_request(request, name, request_id):
can_edit_deadline = can_edit_comment
can_add_comment = can_manage_request
assignments = review_req.reviewassignment_set.all()
for assignment in assignments:
assignment.is_reviewer = user_is_person(request.user, assignment.reviewer.person)
@ -260,6 +262,7 @@ def review_request(request, name, request_id):
'can_assign_reviewer': can_assign_reviewer,
'can_edit_comment': can_edit_comment,
'can_edit_deadline': can_edit_deadline,
'can_add_comment': can_add_comment,
'assignments': assignments,
'wg_chairs': wg_chairs,
'iesg_state_summary': iesg_state_summary,
@ -310,6 +313,31 @@ def close_request(request, name, request_id):
'form': form,
})
class AddCommentForm(forms.Form):
comment = forms.CharField(required=True, widget=forms.Textarea, strip=False)
@login_required
def add_request_comment(request, name, request_id):
doc = get_object_or_404(Document, name=name)
review_req = get_object_or_404(ReviewRequest, pk=request_id)
can_request = is_authorized_in_doc_stream(request.user, doc)
can_manage_request = can_manage_review_requests_for_team(request.user, review_req.team)
if not (can_request or can_manage_request):
permission_denied(request, "You do not have permission to perform this action")
if request.method == "POST":
form = AddCommentForm(request.POST)
if form.is_valid():
c = form.cleaned_data['comment']
review_req.add_history(c)
return redirect(review_request, name=review_req.doc.name, request_id=review_req.pk)
else:
form = AddCommentForm()
return render(request, 'doc/add_comment.html',
dict(doc=doc, form=form, review_req=review_req))
class AssignReviewerForm(forms.Form):
reviewer = PersonEmailChoiceField(label="Assign Additional Reviewer", empty_label="(None)")

View file

@ -143,6 +143,10 @@ class ReviewRequest(models.Model):
def request_closed_time(self):
return self.doc.request_closed_time(self) or self.time
def add_history(self, description):
self._change_reason = description
self.save()
class ReviewAssignment(models.Model):
""" One of possibly many reviews assigned in response to a ReviewRequest """
history = HistoricalRecords(history_change_reason_field=models.TextField(null=True))

View file

@ -1,10 +1,14 @@
# Copyright The IETF Trust 2019-2020, All Rights Reserved
# -*- coding: utf-8 -*-
import datetime
import debug # pyflakes:ignore
from pyquery import PyQuery
from ietf.group.factories import RoleFactory
from ietf.doc.factories import WgDraftFactory
from ietf.utils.mail import empty_outbox, get_payload_text, outbox
from ietf.utils.test_utils import TestCase, reload_db_objects
from ietf.utils.test_utils import login_testing_unauthorized, unicontent
from ietf.utils.timezone import date_today, datetime_from_date
from .factories import ReviewAssignmentFactory, ReviewRequestFactory, ReviewerSettingsFactory
from .mailarch import hash_list_message_id
@ -14,6 +18,7 @@ from .utils import (email_secretary_reminder, review_assignments_needing_secreta
send_reminder_unconfirmed_assignments, send_review_reminder_overdue_assignment,
send_reminder_all_open_reviews, send_unavailability_period_ending_reminder,
ORIGIN_DATE_PERIODIC_REMINDERS)
from django.urls import reverse as urlreverse
class HashTest(TestCase):
@ -508,3 +513,40 @@ class ReviewAssignmentReminderTests(TestCase):
self.assertTrue(self.reviewer.email_address() in log[0])
self.assertTrue('1 open review' in log[0])
class AddReviewCommentTestCase(TestCase):
def test_review_add_comment(self):
draft = WgDraftFactory(name='draft-ietf-mars-test',group__acronym='mars')
review_req = ReviewRequestFactory(doc=draft, state_id='assigned')
ReviewAssignmentFactory(review_request=review_req, state_id='assigned')
url_post = urlreverse('ietf.doc.views_review.add_request_comment', kwargs=dict(name=draft.name, request_id=review_req.pk))
url_page = urlreverse('ietf.doc.views_review.review_request', kwargs=dict(name=draft.name, request_id=review_req.pk))
login_testing_unauthorized(self, "secretary", url_post)
# Check that we do not have entry on the page
r = self.client.get(url_page)
self.assertEqual(r.status_code, 200)
# Needs to have history
self.assertContains(r, 'History')
# But can't have the comment we are goint to add.
self.assertNotContains(r, 'This is a test.')
# Get the form
r = self.client.get(url_post)
self.assertEqual(r.status_code, 200)
q = PyQuery(unicontent(r))
self.assertEqual(len(q('form textarea[name=comment]')), 1)
# Post the comment
r = self.client.post(url_post, dict(comment="This is a test."))
self.assertEqual(r.status_code, 302)
# Get the main page again
r = self.client.get(url_page)
self.assertEqual(r.status_code, 200)
# Needs to have history
self.assertContains(r, 'History')
# But can't have the comment we are goint to add.
self.assertContains(r, 'This is a test.')

View file

@ -2,13 +2,14 @@
{# Copyright The IETF Trust 2015, All Rights Reserved #}
{% load origin %}
{% load django_bootstrap5 %}
{% block title %}Add comment for {{ doc }}{% endblock %}
{% block title %}Add comment for
{% if review_req %} {{ review_req }} {% else %} {{ doc }} {% endif %} {% endblock %}
{% block content %}
{% origin %}
<h1>
Add comment
<br>
<small class="text-body-secondary">{{ doc }}</small>
<small class="text-body-secondary">{% if review_req %} {{ review_req }} {% else %} {{ doc }} {% endif %}</small>
</h1>
<form method="post">
{% csrf_token %}
@ -17,7 +18,12 @@
The comment will be added to the history trail.
</p>
{% bootstrap_button button_type="submit" content="Submit" %}
{% if review_req %}
<a class="btn btn-secondary float-end"
href="{% url "ietf.doc.views_review.review_request" name=doc.name request_id=review_req.pk %}">Back</a>
{% else %}
<a class="btn btn-secondary float-end"
href="{% url "ietf.doc.views_doc.document_main" name=doc.name %}">Back</a>
{% endif %}
</form>
{% endblock %}

View file

@ -21,6 +21,15 @@
</a>
{% endif %}
<h2 class="mt-5">History</h2>
{% if can_add_comment %}
<div class="buttonlist">
<a class="btn btn-primary"
href="{% url 'ietf.doc.views_review.add_request_comment' name=doc.name request_id=review_req.pk %}">
<i class="bi bi-plus"></i>
Add comment
</a>
</div>
{% endif %}
<div id="history">
<table class="table table-sm table-striped tablesorter">
<thead>
@ -30,6 +39,7 @@
<th scope="col" data-sort="description">Description</th>
</tr>
</thead>
<tbody>
{% for h in history %}
{% if h.history_change_reason %}
<tr>
@ -39,6 +49,7 @@
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}