diff --git a/commentaries/templates/commentaries/commentary_detail.html b/commentaries/templates/commentaries/commentary_detail.html index e468065f95c17ca29d3c3cf5d850192aa9fbd558..b9c5fcd2f9a3691477692d54a4441d17f4b8c913 100644 --- a/commentaries/templates/commentaries/commentary_detail.html +++ b/commentaries/templates/commentaries/commentary_detail.html @@ -58,32 +58,6 @@ {% include 'scipost/comments_block.html' %} - -{% if user.is_authenticated and commentary.open_for_commenting and perms.scipost.can_submit_comments %} -<hr> - -<div class="row"> - <div class="col-12"> - <div class="panel"> - <h2>Contribute a Comment:</h2> - </div> - </div> -</div> -<div class="row"> - <div class="col-12"> - <form enctype="multipart/form-data" action="{% url 'commentaries:commentary' arxiv_or_DOI_string=commentary.arxiv_or_DOI_string %}" method="post"> - {% csrf_token %} - {% load crispy_forms_tags %} - {% crispy form %} - </form> - </div> - <div class="col-12"> - <h3>Preview of your comment:</h3> - <p id="preview-comment_text"></p> - </div> -</div> - -{% endif %} - +{% include 'comments/new_comment.html' with object_id=commentary.id type_of_object='commentary' open_for_commenting=commentary.open_for_commenting %} {% endblock content %} diff --git a/commentaries/test_views.py b/commentaries/test_views.py index 606bbfc37dbda31571f533f4d82586aae14f9226..50d6850fd46c2b7166370a078492a227e04dcda5 100644 --- a/commentaries/test_views.py +++ b/commentaries/test_views.py @@ -1,10 +1,10 @@ from django.core.urlresolvers import reverse from django.contrib.auth.models import Group -from django.test import TestCase +from django.test import TestCase, Client from scipost.factories import ContributorFactory -from .factories import UnvettedCommentaryFactory, VettedCommentaryFactory +from .factories import UnvettedCommentaryFactory, VettedCommentaryFactory, UnpublishedVettedCommentaryFactory from .forms import CommentarySearchForm from .models import Commentary @@ -108,3 +108,19 @@ class BrowseCommentariesTest(TestCase): self.assertTrue(response.context['commentary_browse_list'].count() >= 1) # The search form is passed trough the view... self.assertTrue(type(response.context['form']) is CommentarySearchForm) + + +class CommentaryDetailTest(TestCase): + fixtures = ['permissions', 'groups'] + + def setUp(self): + self.client = Client() + self.commentary = UnpublishedVettedCommentaryFactory() + self.target = reverse( + 'commentaries:commentary', + kwargs={'arxiv_or_DOI_string': self.commentary.arxiv_or_DOI_string} + ) + + def test_status_code_200(self): + response = self.client.get(self.target) + self.assertEqual(response.status_code, 200) diff --git a/commentaries/views.py b/commentaries/views.py index 339bab4f935cf0a3bcaefbf36a682982be70c215..1ae2de1ceffbf60e70bfde80aa58b16db5149c22 100644 --- a/commentaries/views.py +++ b/commentaries/views.py @@ -299,45 +299,10 @@ def browse(request, discipline, nrweeksback): def commentary_detail(request, arxiv_or_DOI_string): commentary = get_object_or_404(Commentary, arxiv_or_DOI_string=arxiv_or_DOI_string) comments = commentary.comment_set.all() - if request.method == 'POST': - form = CommentForm(request.POST, request.FILES) - if form.is_valid(): - author = Contributor.objects.get(user=request.user) - newcomment = Comment(commentary=commentary, author=author, - is_rem=form.cleaned_data['is_rem'], - is_que=form.cleaned_data['is_que'], - is_ans=form.cleaned_data['is_ans'], - is_obj=form.cleaned_data['is_obj'], - is_rep=form.cleaned_data['is_rep'], - is_val=form.cleaned_data['is_val'], - is_lit=form.cleaned_data['is_lit'], - is_sug=form.cleaned_data['is_sug'], - file_attachment=form.cleaned_data['file_attachment'], - comment_text=form.cleaned_data['comment_text'], - remarks_for_editors=form.cleaned_data['remarks_for_editors'], - date_submitted=timezone.now(), - ) - newcomment.save() - author.nr_comments = Comment.objects.filter(author=author).count() - author.save() - context = {'ack_header': 'Thank you for contributing a Comment.', - 'ack_message': 'It will soon be vetted by an Editor.', - 'followup_message': 'Back to the ', - 'followup_link': reverse( - 'commentaries:commentary', - kwargs={ - 'arxiv_or_DOI_string': newcomment.commentary.arxiv_or_DOI_string - } - ), - 'followup_link_label': ' Commentary page you came from' - } - return render(request, 'scipost/acknowledgement.html', context) - else: - form = CommentForm() + form = CommentForm() try: - author_replies = Comment.objects.filter(commentary=commentary, - is_author_reply=True, - status__gte=1) + author_replies = Comment.objects.filter( + commentary=commentary, is_author_reply=True, status__gte=1) except Comment.DoesNotExist: author_replies = () context = {'commentary': commentary, diff --git a/comments/test_views.py b/comments/test_views.py index 967c63d3b45cc19aad705bf321b6731b69a27dec..e1824139a5c2dd7def2f41ae2f6c6fd742914e41 100644 --- a/comments/test_views.py +++ b/comments/test_views.py @@ -1,11 +1,13 @@ from django.test import TestCase, RequestFactory, Client from django.urls import reverse, reverse_lazy from django.contrib.auth.models import Group +from django.contrib.messages.storage.fallback import FallbackStorage from django.core.exceptions import PermissionDenied from scipost.factories import ContributorFactory from theses.factories import ThesisLinkFactory from submissions.factories import EICassignedSubmissionFactory +from commentaries.factories import UnpublishedVettedCommentaryFactory from .factories import CommentFactory from .forms import CommentForm @@ -18,6 +20,13 @@ from common.helpers import model_form_data class TestNewComment(TestCase): fixtures = ['groups', 'permissions'] + def install_messages_middleware(self, request): + # I don't know what the following three lines do, but they help make a RequestFactory + # work with the messages middleware + setattr(request, 'session', 'session') + messages = FallbackStorage(request) + setattr(request, '_messages', messages) + def test_submitting_comment_on_thesislink_creates_comment_and_redirects(self): """ Valid Comment gets saved """ @@ -30,6 +39,7 @@ class TestNewComment(TestCase): self.assertEqual(comment_count, 0) request = RequestFactory().post(target, valid_comment_data) + self.install_messages_middleware(request) request.user = contributor.user response = new_comment(request, object_id=thesislink.id, type_of_object='thesislink') @@ -55,6 +65,7 @@ class TestNewComment(TestCase): self.assertEqual(comment_count, 0) request = RequestFactory().post(target, valid_comment_data) + self.install_messages_middleware(request) request.user = contributor.user response = new_comment(request, object_id=submission.id, type_of_object='submission') @@ -69,6 +80,31 @@ class TestNewComment(TestCase): self.assertRedirects(response, expected_redirect_link) + def test_submitting_comment_on_commentary_creates_comment_and_redirects(self): + """ Valid Comment gets saved """ + + contributor = ContributorFactory() + commentary = UnpublishedVettedCommentaryFactory() + valid_comment_data = model_form_data(CommentFactory.build(), CommentForm) + target = reverse('comments:new_comment', kwargs={'object_id': commentary.id, 'type_of_object': 'commentary'}) + + comment_count = Comment.objects.filter(author=contributor).count() + self.assertEqual(comment_count, 0) + + request = RequestFactory().post(target, valid_comment_data) + self.install_messages_middleware(request) + request.user = contributor.user + response = new_comment(request, object_id=commentary.id, type_of_object='commentary') + + comment_count = commentary.comment_set.count() + self.assertEqual(comment_count, 1) + + response.client = Client() + expected_redirect_link = reverse( + 'commentaries:commentary', kwargs={'arxiv_or_DOI_string': commentary.arxiv_or_DOI_string}) + self.assertRedirects(response, expected_redirect_link) + + def test_submitting_comment_on_submission_that_is_not_open_for_commenting_should_be_impossible(self): contributor = ContributorFactory() submission = EICassignedSubmissionFactory() @@ -84,6 +120,7 @@ class TestNewComment(TestCase): self.assertEqual(comment_count, 0) request = RequestFactory().post(target, valid_comment_data) + self.install_messages_middleware(request) request.user = contributor.user with self.assertRaises(PermissionDenied): response = new_comment(request, object_id=submission.id, type_of_object='submission') diff --git a/comments/views.py b/comments/views.py index 48495af77db0a1674aaa9f2256bd668fa05c0fc3..ce859b86553018a6788aee4a82472c71cfa388f8 100644 --- a/comments/views.py +++ b/comments/views.py @@ -1,11 +1,14 @@ from django.utils import timezone from django.shortcuts import get_object_or_404, render, redirect from django.contrib.auth.decorators import permission_required +from django.contrib import messages from django.core.mail import EmailMessage from django.core.urlresolvers import reverse from django.core.exceptions import PermissionDenied from django.http import HttpResponseRedirect, Http404 +import strings + from .models import Comment from .forms import CommentForm, VetCommentForm, comment_refusal_dict @@ -13,6 +16,7 @@ from scipost.models import Contributor, title_dict from theses.models import ThesisLink from submissions.utils import SubmissionUtils from submissions.models import Submission, Report +from commentaries.models import Commentary @permission_required('scipost.can_submit_comments', raise_exception=True) def new_comment(request, **kwargs): @@ -32,14 +36,15 @@ def new_comment(request, **kwargs): is_val=form.cleaned_data['is_val'], is_lit=form.cleaned_data['is_lit'], is_sug=form.cleaned_data['is_sug'], + file_attachment=form.cleaned_data['file_attachment'], comment_text=form.cleaned_data['comment_text'], remarks_for_editors=form.cleaned_data['remarks_for_editors'], date_submitted=timezone.now(), ) if type_of_object == "thesislink": + thesislink = ThesisLink.objects.get(id=object_id) if not thesislink.open_for_commenting: raise PermissionDenied - thesislink = ThesisLink.objects.get(id=object_id) new_comment.thesislink = thesislink redirect_link = reverse('theses:thesis', kwargs={"thesislink_id":thesislink.id}) elif type_of_object == "submission": @@ -52,12 +57,19 @@ def new_comment(request, **kwargs): kwargs={"arxiv_identifier_w_vn_nr": submission.arxiv_identifier_w_vn_nr} ) elif type_of_object == "commentary": - # TODO - 1 + 1 + commentary = Commentary.objects.get(id=object_id) + if not commentary.open_for_commenting: + raise PermissionDenied + new_comment.commentary = commentary + redirect_link = reverse( + 'commentaries:commentary', kwargs={'arxiv_or_DOI_string': commentary.arxiv_or_DOI_string} + ) new_comment.save() author.nr_comments = Comment.objects.filter(author=author).count() author.save() + messages.add_message( + request, messages.SUCCESS, strings.acknowledge_submit_comment) return redirect(redirect_link) else: # This view is only accessible by POST request diff --git a/strings/__init__.py b/strings/__init__.py index f51088e3aeecb9d059e14d341717c77936519e6c..acb0df6ceafab9bb8a85bae4049a9ccb7fdc8cec 100644 --- a/strings/__init__.py +++ b/strings/__init__.py @@ -7,6 +7,9 @@ acknowledge_request_commentary = ( "Your request will soon be handled by an Editor. <br>" "Thank you for your request for a Commentary Page." ) +acknowledge_submit_comment = ( + "Thank you for contributing a Comment. It will soon be vetted by an Editor." +) # Arxiv response is not valid arxiv_caller_errormessages = { diff --git a/submissions/test_views.py b/submissions/test_views.py index 8cfec341050c2f3835c8933a75288e1264d6a28b..bb177e9292a3dc57e2c9a01a91c3a161e47ffb89 100644 --- a/submissions/test_views.py +++ b/submissions/test_views.py @@ -50,7 +50,7 @@ class SubmitManuscriptTest(TestCase): class SubmissionDetailTest(TestCase): - fixtures = ['permissions', 'groups', 'contributors'] + fixtures = ['permissions', 'groups'] def setUp(self): self.client = Client()