feat: add "add comment" feature to the review requests. (#6603)
This commit is contained in:
parent
d5e4ea8183
commit
53d0014826
|
@ -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),
|
||||
|
|
|
@ -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)")
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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.')
|
||||
|
||||
|
|
|
@ -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 %}
|
|
@ -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 %}
|
||||
|
|
Loading…
Reference in a new issue