fix(spec): enforce read-time budget and re-render invalid comment submissions
This commit is contained in:
@@ -63,6 +63,34 @@ def test_comment_post_rejected_when_comments_disabled(client, home_page):
|
||||
assert Comment.objects.count() == 0
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_invalid_comment_post_rerenders_form_with_errors(client, home_page):
|
||||
cache.clear()
|
||||
index = ArticleIndexPage(title="Articles", slug="articles")
|
||||
home_page.add_child(instance=index)
|
||||
author = AuthorFactory()
|
||||
article = ArticlePage(title="A", slug="a", author=author, summary="s", body=[("rich_text", "<p>body</p>")])
|
||||
index.add_child(instance=article)
|
||||
article.save_revision().publish()
|
||||
|
||||
resp = client.post(
|
||||
"/comments/post/",
|
||||
{
|
||||
"article_id": article.id,
|
||||
"author_name": "Test",
|
||||
"author_email": "test@example.com",
|
||||
"body": " ",
|
||||
"honeypot": "",
|
||||
},
|
||||
)
|
||||
|
||||
assert resp.status_code == 200
|
||||
assert b'aria-label="Comment form errors"' in resp.content
|
||||
assert b'value="Test"' in resp.content
|
||||
assert b"test@example.com" in resp.content
|
||||
assert Comment.objects.count() == 0
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_comment_reply_depth_is_enforced(client, home_page):
|
||||
cache.clear()
|
||||
@@ -100,7 +128,8 @@ def test_comment_reply_depth_is_enforced(client, home_page):
|
||||
"honeypot": "",
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 302
|
||||
assert resp.status_code == 200
|
||||
assert b"Reply depth exceeds the allowed limit" in resp.content
|
||||
assert Comment.objects.count() == 2
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ from django.contrib import messages
|
||||
from django.core.cache import cache
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.views import View
|
||||
|
||||
from apps.blog.models import ArticlePage
|
||||
@@ -23,6 +23,12 @@ def client_ip_from_request(request) -> str:
|
||||
|
||||
|
||||
class CommentCreateView(View):
|
||||
def _render_article_with_errors(self, request, article, form):
|
||||
context = article.get_context(request)
|
||||
context["page"] = article
|
||||
context["comment_form"] = form
|
||||
return render(request, "blog/article_page.html", context, status=200)
|
||||
|
||||
def post(self, request):
|
||||
ip = client_ip_from_request(request)
|
||||
key = f"comment-rate:{ip}"
|
||||
@@ -48,11 +54,10 @@ class CommentCreateView(View):
|
||||
try:
|
||||
comment.full_clean()
|
||||
except ValidationError:
|
||||
messages.error(request, "Reply depth exceeds the allowed limit")
|
||||
return redirect(article.url)
|
||||
form.add_error(None, "Reply depth exceeds the allowed limit")
|
||||
return self._render_article_with_errors(request, article, form)
|
||||
comment.save()
|
||||
messages.success(request, "Your comment is awaiting moderation")
|
||||
return redirect(f"{article.url}?commented=1")
|
||||
|
||||
messages.error(request, "Please correct the form errors")
|
||||
return redirect(article.url)
|
||||
return self._render_article_with_errors(request, article, form)
|
||||
|
||||
@@ -72,3 +72,4 @@ def test_read_time_benchmark(benchmark):
|
||||
|
||||
result = benchmark(article._compute_read_time)
|
||||
assert result >= 1
|
||||
assert benchmark.stats.stats.mean < 0.05
|
||||
|
||||
Reference in New Issue
Block a user