Commit 4412bb996e219b088ee15fbeff4ba733201c8420

Authored by Jacob Kaplan-Moss
1 parent 222f604e

Tests pass (Python 2.7, Django 1.5).

@@ -2,11 +2,12 @@ from __future__ import unicode_literals @@ -2,11 +2,12 @@ from __future__ import unicode_literals
2 2
3 from django.contrib import admin 3 from django.contrib import admin
4 from django.contrib.auth import get_user_model 4 from django.contrib.auth import get_user_model
5 -from django.utils.translation import ugettext_lazy as _, ungettext, ungettext_lazy  
6 -from django.contrib.comments.views.moderation import perform_flag, perform_approve, perform_delete 5 +from django.utils.translation import ugettext_lazy as _, ungettext
7 6
8 -from django_comments import get_model  
9 from django_comments.models import Comment 7 from django_comments.models import Comment
  8 +from django_comments import get_model
  9 +from django_comments.views.moderation import perform_flag, perform_approve, perform_delete
  10 +
10 11
11 class UsernameSearch(object): 12 class UsernameSearch(object):
12 """The User object may not be auth.User, so we need to provide 13 """The User object may not be auth.User, so we need to provide
@@ -43,7 +44,7 @@ class CommentsAdmin(admin.ModelAdmin): @@ -43,7 +44,7 @@ class CommentsAdmin(admin.ModelAdmin):
43 # Only superusers should be able to delete the comments from the DB. 44 # Only superusers should be able to delete the comments from the DB.
44 if not request.user.is_superuser and 'delete_selected' in actions: 45 if not request.user.is_superuser and 'delete_selected' in actions:
45 actions.pop('delete_selected') 46 actions.pop('delete_selected')
46 - if not request.user.has_perm('comments.can_moderate'): 47 + if not request.user.has_perm('django_comments.can_moderate'):
47 if 'approve_comments' in actions: 48 if 'approve_comments' in actions:
48 actions.pop('approve_comments') 49 actions.pop('approve_comments')
49 if 'remove_comments' in actions: 50 if 'remove_comments' in actions:
@@ -52,20 +53,17 @@ class CommentsAdmin(admin.ModelAdmin): @@ -52,20 +53,17 @@ class CommentsAdmin(admin.ModelAdmin):
52 53
53 def flag_comments(self, request, queryset): 54 def flag_comments(self, request, queryset):
54 self._bulk_flag(request, queryset, perform_flag, 55 self._bulk_flag(request, queryset, perform_flag,
55 - ungettext_lazy('%d comment was successfully flagged',  
56 - '%d comments were successfully flagged')) 56 + lambda n: ungettext('flagged', 'flagged', n))
57 flag_comments.short_description = _("Flag selected comments") 57 flag_comments.short_description = _("Flag selected comments")
58 58
59 def approve_comments(self, request, queryset): 59 def approve_comments(self, request, queryset):
60 self._bulk_flag(request, queryset, perform_approve, 60 self._bulk_flag(request, queryset, perform_approve,
61 - ungettext_lazy('%d comment was successfully approved',  
62 - '%d comments were successfully approved')) 61 + lambda n: ungettext('approved', 'approved', n))
63 approve_comments.short_description = _("Approve selected comments") 62 approve_comments.short_description = _("Approve selected comments")
64 63
65 def remove_comments(self, request, queryset): 64 def remove_comments(self, request, queryset):
66 self._bulk_flag(request, queryset, perform_delete, 65 self._bulk_flag(request, queryset, perform_delete,
67 - ungettext_lazy('%d comment was successfully removed',  
68 - '%d comments were successfully removed')) 66 + lambda n: ungettext('removed', 'removed', n))
69 remove_comments.short_description = _("Remove selected comments") 67 remove_comments.short_description = _("Remove selected comments")
70 68
71 def _bulk_flag(self, request, queryset, action, done_message): 69 def _bulk_flag(self, request, queryset, action, done_message):
@@ -78,7 +76,10 @@ class CommentsAdmin(admin.ModelAdmin): @@ -78,7 +76,10 @@ class CommentsAdmin(admin.ModelAdmin):
78 action(request, comment) 76 action(request, comment)
79 n_comments += 1 77 n_comments += 1
80 78
81 - self.message_user(request, done_message % n_comments) 79 + msg = ungettext('1 comment was successfully %(action)s.',
  80 + '%(count)s comments were successfully %(action)s.',
  81 + n_comments)
  82 + self.message_user(request, msg % {'count': n_comments, 'action': done_message(n_comments)})
82 83
83 # Only register the default admin if the model is the built-in comment model 84 # Only register the default admin if the model is the built-in comment model
84 # (this won't be true if there's a custom comment app). 85 # (this won't be true if there's a custom comment app).
@@ -8,7 +8,7 @@ class CommentManager(models.Manager): @@ -8,7 +8,7 @@ class CommentManager(models.Manager):
8 """ 8 """
9 QuerySet for all comments currently in the moderation queue. 9 QuerySet for all comments currently in the moderation queue.
10 """ 10 """
11 - return self.get_queryset().filter(is_public=False, is_removed=False) 11 + return self.get_query_set().filter(is_public=False, is_removed=False)
12 12
13 def for_model(self, model): 13 def for_model(self, model):
14 """ 14 """
@@ -16,7 +16,7 @@ class CommentManager(models.Manager): @@ -16,7 +16,7 @@ class CommentManager(models.Manager):
16 a class). 16 a class).
17 """ 17 """
18 ct = ContentType.objects.get_for_model(model) 18 ct = ContentType.objects.get_for_model(model)
19 - qs = self.get_queryset().filter(content_type=ct) 19 + qs = self.get_query_set().filter(content_type=ct)
20 if isinstance(model, models.Model): 20 if isinstance(model, models.Model):
21 qs = qs.filter(object_pk=force_text(model._get_pk_val())) 21 qs = qs.filter(object_pk=force_text(model._get_pk_val()))
22 return qs 22 return qs
@@ -303,7 +303,7 @@ class Moderator(object): @@ -303,7 +303,7 @@ class Moderator(object):
303 model_or_iterable = [model_or_iterable] 303 model_or_iterable = [model_or_iterable]
304 for model in model_or_iterable: 304 for model in model_or_iterable:
305 if model in self._registry: 305 if model in self._registry:
306 - raise AlreadyModerated("The model '%s' is already being moderated" % model._meta.model_name) 306 + raise AlreadyModerated("The model '%s' is already being moderated" % model._meta.module_name)
307 self._registry[model] = moderation_class(model) 307 self._registry[model] = moderation_class(model)
308 308
309 def unregister(self, model_or_iterable): 309 def unregister(self, model_or_iterable):
@@ -319,7 +319,7 @@ class Moderator(object): @@ -319,7 +319,7 @@ class Moderator(object):
319 model_or_iterable = [model_or_iterable] 319 model_or_iterable = [model_or_iterable]
320 for model in model_or_iterable: 320 for model in model_or_iterable:
321 if model not in self._registry: 321 if model not in self._registry:
322 - raise NotModerated("The model '%s' is not currently being moderated" % model._meta.model_name) 322 + raise NotModerated("The model '%s' is not currently being moderated" % model._meta.module_name)
323 del self._registry[model] 323 del self._registry[model]
324 324
325 def pre_save_moderation(self, sender, comment, request, **kwargs): 325 def pre_save_moderation(self, sender, comment, request, **kwargs):
@@ -2,8 +2,6 @@ from django import template @@ -2,8 +2,6 @@ from django import template
2 from django.template.loader import render_to_string 2 from django.template.loader import render_to_string
3 from django.conf import settings 3 from django.conf import settings
4 from django.contrib.contenttypes.models import ContentType 4 from django.contrib.contenttypes.models import ContentType
5 -from django.utils import six  
6 -from django.utils.deprecation import RenameMethodsBase  
7 from django.utils.encoding import smart_text 5 from django.utils.encoding import smart_text
8 6
9 import django_comments 7 import django_comments
@@ -11,13 +9,7 @@ import django_comments @@ -11,13 +9,7 @@ import django_comments
11 register = template.Library() 9 register = template.Library()
12 10
13 11
14 -class RenameBaseCommentNodeMethods(RenameMethodsBase):  
15 - renamed_methods = (  
16 - ('get_query_set', 'get_queryset', PendingDeprecationWarning),  
17 - )  
18 -  
19 -  
20 -class BaseCommentNode(six.with_metaclass(RenameBaseCommentNodeMethods, template.Node)): 12 +class BaseCommentNode(template.Node):
21 """ 13 """
22 Base helper class (abstract) for handling the get_comment_* template tags. 14 Base helper class (abstract) for handling the get_comment_* template tags.
23 Looks a bit strange, but the subclasses below should make this a bit more 15 Looks a bit strange, but the subclasses below should make this a bit more
@@ -74,11 +66,11 @@ class BaseCommentNode(six.with_metaclass(RenameBaseCommentNodeMethods, template. @@ -74,11 +66,11 @@ class BaseCommentNode(six.with_metaclass(RenameBaseCommentNodeMethods, template.
74 self.comment = comment 66 self.comment = comment
75 67
76 def render(self, context): 68 def render(self, context):
77 - qs = self.get_queryset(context) 69 + qs = self.get_query_set(context)
78 context[self.as_varname] = self.get_context_value_from_queryset(context, qs) 70 context[self.as_varname] = self.get_context_value_from_queryset(context, qs)
79 return '' 71 return ''
80 72
81 - def get_queryset(self, context): 73 + def get_query_set(self, context):
82 ctype, object_pk = self.get_target_ctype_pk(context) 74 ctype, object_pk = self.get_target_ctype_pk(context)
83 if not object_pk: 75 if not object_pk:
84 return self.comment_model.objects.none() 76 return self.comment_model.objects.none()
@@ -215,7 +207,7 @@ class RenderCommentListNode(CommentListNode): @@ -215,7 +207,7 @@ class RenderCommentListNode(CommentListNode):
215 "comments/%s/list.html" % ctype.app_label, 207 "comments/%s/list.html" % ctype.app_label,
216 "comments/list.html" 208 "comments/list.html"
217 ] 209 ]
218 - qs = self.get_queryset(context) 210 + qs = self.get_query_set(context)
219 context.push() 211 context.push()
220 liststr = render_to_string(template_search_list, { 212 liststr = render_to_string(template_search_list, {
221 "comment_list" : self.get_context_value_from_queryset(context, qs) 213 "comment_list" : self.get_context_value_from_queryset(context, qs)
@@ -86,10 +86,10 @@ def post_comment(request, next=None, using=None): @@ -86,10 +86,10 @@ def post_comment(request, next=None, using=None):
86 # These first two exist for purely historical reasons. 86 # These first two exist for purely historical reasons.
87 # Django v1.0 and v1.1 allowed the underscore format for 87 # Django v1.0 and v1.1 allowed the underscore format for
88 # preview templates, so we have to preserve that format. 88 # preview templates, so we have to preserve that format.
89 - "comments/%s_%s_preview.html" % (model._meta.app_label, model._meta.model_name), 89 + "comments/%s_%s_preview.html" % (model._meta.app_label, model._meta.module_name),
90 "comments/%s_preview.html" % model._meta.app_label, 90 "comments/%s_preview.html" % model._meta.app_label,
91 # Now the usual directory based template hierarchy. 91 # Now the usual directory based template hierarchy.
92 - "comments/%s/%s/preview.html" % (model._meta.app_label, model._meta.model_name), 92 + "comments/%s/%s/preview.html" % (model._meta.app_label, model._meta.module_name),
93 "comments/%s/preview.html" % model._meta.app_label, 93 "comments/%s/preview.html" % model._meta.app_label,
94 "comments/preview.html", 94 "comments/preview.html",
95 ] 95 ]
@@ -37,7 +37,7 @@ def flag(request, comment_id, next=None): @@ -37,7 +37,7 @@ def flag(request, comment_id, next=None):
37 ) 37 )
38 38
39 @csrf_protect 39 @csrf_protect
40 -@permission_required("comments.can_moderate") 40 +@permission_required("django_comments.can_moderate")
41 def delete(request, comment_id, next=None): 41 def delete(request, comment_id, next=None):
42 """ 42 """
43 Deletes a comment. Confirmation on GET, action on POST. Requires the "can 43 Deletes a comment. Confirmation on GET, action on POST. Requires the "can
@@ -65,7 +65,7 @@ def delete(request, comment_id, next=None): @@ -65,7 +65,7 @@ def delete(request, comment_id, next=None):
65 ) 65 )
66 66
67 @csrf_protect 67 @csrf_protect
68 -@permission_required("comments.can_moderate") 68 +@permission_required("django_comments.can_moderate")
69 def approve(request, comment_id, next=None): 69 def approve(request, comment_id, next=None):
70 """ 70 """
71 Approve a comment (that is, mark it as public and non-removed). Confirmation 71 Approve a comment (that is, mark it as public and non-removed). Confirmation
@@ -17,6 +17,7 @@ settings.configure( @@ -17,6 +17,7 @@ settings.configure(
17 INSTALLED_APPS = [ 17 INSTALLED_APPS = [
18 "django.contrib.auth", 18 "django.contrib.auth",
19 "django.contrib.contenttypes", 19 "django.contrib.contenttypes",
  20 + "django.contrib.sessions",
20 "django.contrib.sites", 21 "django.contrib.sites",
21 "django.contrib.admin", 22 "django.contrib.admin",
22 "django_comments", 23 "django_comments",
@@ -31,8 +32,8 @@ settings.configure( @@ -31,8 +32,8 @@ settings.configure(
31 from django.test.simple import DjangoTestSuiteRunner 32 from django.test.simple import DjangoTestSuiteRunner
32 33
33 def main(): 34 def main():
34 - runner = DjangoTestSuiteRunner()  
35 - failures = runner.run_tests(['testapp'], verbosity=1, interactive=True) 35 + runner = DjangoTestSuiteRunner(failfast=True, verbosity=1)
  36 + failures = runner.run_tests(['testapp'], interactive=True)
36 sys.exit(failures) 37 sys.exit(failures)
37 38
38 if __name__ == '__main__': 39 if __name__ == '__main__':
  1 +A comment has been posted on {{ content_object }}.
  2 +The comment reads as follows:
  3 +{{ comment }}
@@ -94,3 +94,4 @@ from .templatetag_tests import * @@ -94,3 +94,4 @@ from .templatetag_tests import *
94 from .comment_view_tests import * 94 from .comment_view_tests import *
95 from .moderation_view_tests import * 95 from .moderation_view_tests import *
96 from .comment_utils_moderators_tests import * 96 from .comment_utils_moderators_tests import *
  97 +
1 from __future__ import absolute_import 1 from __future__ import absolute_import
2 2
3 from django.core import mail 3 from django.core import mail
  4 +from django.test.utils import override_settings
4 5
5 from django_comments.models import Comment 6 from django_comments.models import Comment
6 from django_comments.moderation import (moderator, CommentModerator, 7 from django_comments.moderation import (moderator, CommentModerator,
@@ -68,9 +69,10 @@ class CommentUtilsModeratorTests(CommentTestCase): @@ -68,9 +69,10 @@ class CommentUtilsModeratorTests(CommentTestCase):
68 self.assertRaises(AlreadyModerated, moderator.register, Entry, EntryModerator1) 69 self.assertRaises(AlreadyModerated, moderator.register, Entry, EntryModerator1)
69 70
70 def testEmailNotification(self): 71 def testEmailNotification(self):
71 - moderator.register(Entry, EntryModerator1)  
72 - self.createSomeComments()  
73 - self.assertEqual(len(mail.outbox), 2) 72 + with override_settings(MANAGERS=("test@example.com",)):
  73 + moderator.register(Entry, EntryModerator1)
  74 + self.createSomeComments()
  75 + self.assertEqual(len(mail.outbox), 2)
74 76
75 def testCommentsEnabled(self): 77 def testCommentsEnabled(self):
76 moderator.register(Entry, EntryModerator2) 78 moderator.register(Entry, EntryModerator2)
@@ -262,7 +262,7 @@ class AdminActionsTests(CommentTestCase): @@ -262,7 +262,7 @@ class AdminActionsTests(CommentTestCase):
262 u = User.objects.get(username="normaluser") 262 u = User.objects.get(username="normaluser")
263 u.is_staff = True 263 u.is_staff = True
264 perms = Permission.objects.filter( 264 perms = Permission.objects.filter(
265 - content_type__app_label = 'comments', 265 + content_type__app_label = 'django_comments',
266 codename__endswith = 'comment' 266 codename__endswith = 'comment'
267 ) 267 )
268 for perm in perms: 268 for perm in perms:
@@ -272,31 +272,34 @@ class AdminActionsTests(CommentTestCase): @@ -272,31 +272,34 @@ class AdminActionsTests(CommentTestCase):
272 def testActionsNonModerator(self): 272 def testActionsNonModerator(self):
273 comments = self.createSomeComments() 273 comments = self.createSomeComments()
274 self.client.login(username="normaluser", password="normaluser") 274 self.client.login(username="normaluser", password="normaluser")
275 - response = self.client.get("/admin/comments/comment/") 275 + response = self.client.get("/admin/django_comments/comment/")
276 self.assertNotContains(response, "approve_comments") 276 self.assertNotContains(response, "approve_comments")
277 277
278 def testActionsModerator(self): 278 def testActionsModerator(self):
279 comments = self.createSomeComments() 279 comments = self.createSomeComments()
280 makeModerator("normaluser") 280 makeModerator("normaluser")
281 self.client.login(username="normaluser", password="normaluser") 281 self.client.login(username="normaluser", password="normaluser")
282 - response = self.client.get("/admin/comments/comment/") 282 + response = self.client.get("/admin/django_comments/comment/")
283 self.assertContains(response, "approve_comments") 283 self.assertContains(response, "approve_comments")
284 284
285 def testActionsDisabledDelete(self): 285 def testActionsDisabledDelete(self):
286 "Tests a CommentAdmin where 'delete_selected' has been disabled." 286 "Tests a CommentAdmin where 'delete_selected' has been disabled."
287 comments = self.createSomeComments() 287 comments = self.createSomeComments()
288 self.client.login(username="normaluser", password="normaluser") 288 self.client.login(username="normaluser", password="normaluser")
289 - response = self.client.get('/admin2/comments/comment/') 289 + response = self.client.get('/admin2/django_comments/comment/')
290 self.assertEqual(response.status_code, 200) 290 self.assertEqual(response.status_code, 200)
291 self.assertNotContains(response, '<option value="delete_selected">') 291 self.assertNotContains(response, '<option value="delete_selected">')
292 292
293 def performActionAndCheckMessage(self, action, action_params, expected_message): 293 def performActionAndCheckMessage(self, action, action_params, expected_message):
294 - response = self.client.post('/admin/comments/comment/', 294 + response = self.client.post('/admin/django_comments/comment/',
295 data={'_selected_action': action_params, 295 data={'_selected_action': action_params,
296 'action': action, 296 'action': action,
297 'index': 0}, 297 'index': 0},
298 follow=True) 298 follow=True)
299 - self.assertContains(response, expected_message) 299 + messages = list(m.message for m in response.context['messages'])
  300 + self.assert_(expected_message in messages,
  301 + ("Expected message '%s' wasn't set (messages were: %s)" %
  302 + (expected_message, messages)))
300 303
301 def testActionsMessageTranslations(self): 304 def testActionsMessageTranslations(self):
302 c1, c2, c3, c4 = self.createSomeComments() 305 c1, c2, c3, c4 = self.createSomeComments()
@@ -306,11 +309,11 @@ class AdminActionsTests(CommentTestCase): @@ -306,11 +309,11 @@ class AdminActionsTests(CommentTestCase):
306 self.client.login(username="normaluser", password="normaluser") 309 self.client.login(username="normaluser", password="normaluser")
307 with translation.override('en'): 310 with translation.override('en'):
308 #Test approving 311 #Test approving
309 - self.performActionAndCheckMessage('approve_comments', one_comment, '1 comment was successfully approved')  
310 - self.performActionAndCheckMessage('approve_comments', many_comments, '3 comments were successfully approved') 312 + self.performActionAndCheckMessage('approve_comments', one_comment, '1 comment was successfully approved.')
  313 + self.performActionAndCheckMessage('approve_comments', many_comments, '3 comments were successfully approved.')
311 #Test flagging 314 #Test flagging
312 - self.performActionAndCheckMessage('flag_comments', one_comment, '1 comment was successfully flagged')  
313 - self.performActionAndCheckMessage('flag_comments', many_comments, '3 comments were successfully flagged') 315 + self.performActionAndCheckMessage('flag_comments', one_comment, '1 comment was successfully flagged.')
  316 + self.performActionAndCheckMessage('flag_comments', many_comments, '3 comments were successfully flagged.')
314 #Test removing 317 #Test removing
315 - self.performActionAndCheckMessage('remove_comments', one_comment, '1 comment was successfully removed')  
316 - self.performActionAndCheckMessage('remove_comments', many_comments, '3 comments were successfully removed') 318 + self.performActionAndCheckMessage('remove_comments', one_comment, '1 comment was successfully removed.')
  319 + self.performActionAndCheckMessage('remove_comments', many_comments, '3 comments were successfully removed.')
@@ -4,7 +4,7 @@ from django.conf.urls import patterns, url @@ -4,7 +4,7 @@ from django.conf.urls import patterns, url
4 4
5 from django_comments.feeds import LatestCommentFeed 5 from django_comments.feeds import LatestCommentFeed
6 6
7 -from .custom_comments import views 7 +from custom_comments import views
8 8
9 9
10 feeds = { 10 feeds = {
Please register or login to post a comment