283 lines
12 KiB
Python
283 lines
12 KiB
Python
import re
|
|
from django.conf import settings
|
|
from django.contrib.auth.models import User
|
|
from django.contrib.comments import signals
|
|
from django.contrib.comments.models import Comment
|
|
from regressiontests.comment_tests.models import Article, Book
|
|
from regressiontests.comment_tests.tests import CommentTestCase
|
|
|
|
post_redirect_re = re.compile(r'^http://testserver/posted/\?c=(?P<pk>\d+$)')
|
|
|
|
class CommentViewTests(CommentTestCase):
|
|
|
|
def testPostCommentHTTPMethods(self):
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
response = self.client.get("/post/", data)
|
|
self.assertEqual(response.status_code, 405)
|
|
self.assertEqual(response["Allow"], "POST")
|
|
|
|
def testPostCommentMissingCtype(self):
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
del data["content_type"]
|
|
response = self.client.post("/post/", data)
|
|
self.assertEqual(response.status_code, 400)
|
|
|
|
def testPostCommentBadCtype(self):
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
data["content_type"] = "Nobody expects the Spanish Inquisition!"
|
|
response = self.client.post("/post/", data)
|
|
self.assertEqual(response.status_code, 400)
|
|
|
|
def testPostCommentMissingObjectPK(self):
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
del data["object_pk"]
|
|
response = self.client.post("/post/", data)
|
|
self.assertEqual(response.status_code, 400)
|
|
|
|
def testPostCommentBadObjectPK(self):
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
data["object_pk"] = "14"
|
|
response = self.client.post("/post/", data)
|
|
self.assertEqual(response.status_code, 400)
|
|
|
|
def testPostInvalidIntegerPK(self):
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
data["comment"] = "This is another comment"
|
|
data["object_pk"] = u'\ufffd'
|
|
response = self.client.post("/post/", data)
|
|
self.assertEqual(response.status_code, 400)
|
|
|
|
def testPostInvalidDecimalPK(self):
|
|
b = Book.objects.get(pk='12.34')
|
|
data = self.getValidData(b)
|
|
data["comment"] = "This is another comment"
|
|
data["object_pk"] = 'cookies'
|
|
response = self.client.post("/post/", data)
|
|
self.assertEqual(response.status_code, 400)
|
|
|
|
def testCommentPreview(self):
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
data["preview"] = "Preview"
|
|
response = self.client.post("/post/", data)
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertTemplateUsed(response, "comments/preview.html")
|
|
|
|
def testHashTampering(self):
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
data["security_hash"] = "Nobody expects the Spanish Inquisition!"
|
|
response = self.client.post("/post/", data)
|
|
self.assertEqual(response.status_code, 400)
|
|
|
|
def testDebugCommentErrors(self):
|
|
"""The debug error template should be shown only if DEBUG is True"""
|
|
olddebug = settings.DEBUG
|
|
|
|
settings.DEBUG = True
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
data["security_hash"] = "Nobody expects the Spanish Inquisition!"
|
|
response = self.client.post("/post/", data)
|
|
self.assertEqual(response.status_code, 400)
|
|
self.assertTemplateUsed(response, "comments/400-debug.html")
|
|
|
|
settings.DEBUG = False
|
|
response = self.client.post("/post/", data)
|
|
self.assertEqual(response.status_code, 400)
|
|
self.assertTemplateNotUsed(response, "comments/400-debug.html")
|
|
|
|
settings.DEBUG = olddebug
|
|
|
|
def testCreateValidComment(self):
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
self.response = self.client.post("/post/", data, REMOTE_ADDR="1.2.3.4")
|
|
self.assertEqual(self.response.status_code, 302)
|
|
self.assertEqual(Comment.objects.count(), 1)
|
|
c = Comment.objects.all()[0]
|
|
self.assertEqual(c.ip_address, "1.2.3.4")
|
|
self.assertEqual(c.comment, "This is my comment")
|
|
|
|
def testPostAsAuthenticatedUser(self):
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
data['name'] = data['email'] = ''
|
|
self.client.login(username="normaluser", password="normaluser")
|
|
self.response = self.client.post("/post/", data, REMOTE_ADDR="1.2.3.4")
|
|
self.assertEqual(self.response.status_code, 302)
|
|
self.assertEqual(Comment.objects.count(), 1)
|
|
c = Comment.objects.all()[0]
|
|
self.assertEqual(c.ip_address, "1.2.3.4")
|
|
u = User.objects.get(username='normaluser')
|
|
self.assertEqual(c.user, u)
|
|
self.assertEqual(c.user_name, u.get_full_name())
|
|
self.assertEqual(c.user_email, u.email)
|
|
|
|
def testPostAsAuthenticatedUserWithoutFullname(self):
|
|
"""
|
|
Check that the user's name in the comment is populated for
|
|
authenticated users without first_name and last_name.
|
|
"""
|
|
user = User.objects.create_user(username='jane_other',
|
|
email='jane@example.com', password='jane_other')
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
data['name'] = data['email'] = ''
|
|
self.client.login(username="jane_other", password="jane_other")
|
|
self.response = self.client.post("/post/", data, REMOTE_ADDR="1.2.3.4")
|
|
c = Comment.objects.get(user=user)
|
|
self.assertEqual(c.ip_address, "1.2.3.4")
|
|
self.assertEqual(c.user_name, 'jane_other')
|
|
user.delete()
|
|
|
|
def testPreventDuplicateComments(self):
|
|
"""Prevent posting the exact same comment twice"""
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
self.client.post("/post/", data)
|
|
self.client.post("/post/", data)
|
|
self.assertEqual(Comment.objects.count(), 1)
|
|
|
|
# This should not trigger the duplicate prevention
|
|
self.client.post("/post/", dict(data, comment="My second comment."))
|
|
self.assertEqual(Comment.objects.count(), 2)
|
|
|
|
def testCommentSignals(self):
|
|
"""Test signals emitted by the comment posting view"""
|
|
|
|
# callback
|
|
def receive(sender, **kwargs):
|
|
self.assertEqual(kwargs['comment'].comment, "This is my comment")
|
|
self.assertTrue('request' in kwargs)
|
|
received_signals.append(kwargs.get('signal'))
|
|
|
|
# Connect signals and keep track of handled ones
|
|
received_signals = []
|
|
expected_signals = [
|
|
signals.comment_will_be_posted, signals.comment_was_posted
|
|
]
|
|
for signal in expected_signals:
|
|
signal.connect(receive)
|
|
|
|
# Post a comment and check the signals
|
|
self.testCreateValidComment()
|
|
self.assertEqual(received_signals, expected_signals)
|
|
|
|
for signal in expected_signals:
|
|
signal.disconnect(receive)
|
|
|
|
def testWillBePostedSignal(self):
|
|
"""
|
|
Test that the comment_will_be_posted signal can prevent the comment from
|
|
actually getting saved
|
|
"""
|
|
def receive(sender, **kwargs): return False
|
|
signals.comment_will_be_posted.connect(receive, dispatch_uid="comment-test")
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
response = self.client.post("/post/", data)
|
|
self.assertEqual(response.status_code, 400)
|
|
self.assertEqual(Comment.objects.count(), 0)
|
|
signals.comment_will_be_posted.disconnect(dispatch_uid="comment-test")
|
|
|
|
def testWillBePostedSignalModifyComment(self):
|
|
"""
|
|
Test that the comment_will_be_posted signal can modify a comment before
|
|
it gets posted
|
|
"""
|
|
def receive(sender, **kwargs):
|
|
# a bad but effective spam filter :)...
|
|
kwargs['comment'].is_public = False
|
|
|
|
signals.comment_will_be_posted.connect(receive)
|
|
self.testCreateValidComment()
|
|
c = Comment.objects.all()[0]
|
|
self.assertFalse(c.is_public)
|
|
|
|
def testCommentNext(self):
|
|
"""Test the different "next" actions the comment view can take"""
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
response = self.client.post("/post/", data)
|
|
location = response["Location"]
|
|
match = post_redirect_re.match(location)
|
|
self.assertTrue(match != None, "Unexpected redirect location: %s" % location)
|
|
|
|
data["next"] = "/somewhere/else/"
|
|
data["comment"] = "This is another comment"
|
|
response = self.client.post("/post/", data)
|
|
location = response["Location"]
|
|
match = re.search(r"^http://testserver/somewhere/else/\?c=\d+$", location)
|
|
self.assertTrue(match != None, "Unexpected redirect location: %s" % location)
|
|
|
|
def testCommentDoneView(self):
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
response = self.client.post("/post/", data)
|
|
location = response["Location"]
|
|
match = post_redirect_re.match(location)
|
|
self.assertTrue(match != None, "Unexpected redirect location: %s" % location)
|
|
pk = int(match.group('pk'))
|
|
response = self.client.get(location)
|
|
self.assertTemplateUsed(response, "comments/posted.html")
|
|
self.assertEqual(response.context[0]["comment"], Comment.objects.get(pk=pk))
|
|
|
|
def testCommentNextWithQueryString(self):
|
|
"""
|
|
The `next` key needs to handle already having a query string (#10585)
|
|
"""
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
data["next"] = "/somewhere/else/?foo=bar"
|
|
data["comment"] = "This is another comment"
|
|
response = self.client.post("/post/", data)
|
|
location = response["Location"]
|
|
match = re.search(r"^http://testserver/somewhere/else/\?foo=bar&c=\d+$", location)
|
|
self.assertTrue(match != None, "Unexpected redirect location: %s" % location)
|
|
|
|
def testCommentPostRedirectWithInvalidIntegerPK(self):
|
|
"""
|
|
Tests that attempting to retrieve the location specified in the
|
|
post redirect, after adding some invalid data to the expected
|
|
querystring it ends with, doesn't cause a server error.
|
|
"""
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
data["comment"] = "This is another comment"
|
|
response = self.client.post("/post/", data)
|
|
location = response["Location"]
|
|
broken_location = location + u"\ufffd"
|
|
response = self.client.get(broken_location)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
def testCommentNextWithQueryStringAndAnchor(self):
|
|
"""
|
|
The `next` key needs to handle already having an anchor. Refs #13411.
|
|
"""
|
|
# With a query string also.
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
data["next"] = "/somewhere/else/?foo=bar#baz"
|
|
data["comment"] = "This is another comment"
|
|
response = self.client.post("/post/", data)
|
|
location = response["Location"]
|
|
match = re.search(r"^http://testserver/somewhere/else/\?foo=bar&c=\d+#baz$", location)
|
|
self.assertTrue(match != None, "Unexpected redirect location: %s" % location)
|
|
|
|
# Without a query string
|
|
a = Article.objects.get(pk=1)
|
|
data = self.getValidData(a)
|
|
data["next"] = "/somewhere/else/#baz"
|
|
data["comment"] = "This is another comment"
|
|
response = self.client.post("/post/", data)
|
|
location = response["Location"]
|
|
match = re.search(r"^http://testserver/somewhere/else/\?c=\d+#baz$", location)
|
|
self.assertTrue(match != None, "Unexpected redirect location: %s" % location)
|