def test_notify_comment_followers(self): # send a couple of comments to the article with followup=True and check # that when the second comment is confirmed a followup notification # email is sent to the user who sent the first comment self.assertEqual(self.mock_mailer.call_count, 1) confirm_comment_url(self.key) # no comment followers yet: self.assertEqual(self.mock_mailer.call_count, 1) # send 2nd comment self.form = get_form()(self.article) data = {"name": "Alice", "email": "*****@*****.**", "followup": True, "reply_to": 0, "level": 1, "order": 1, "comment": "Es war einmal eine kleine..."} data.update(self.form.initial) response = post_article_comment(data, article=self.article) self.assertEqual(response.status_code, 302) self.assertTrue(response.url.startswith('/comments/posted/?c=')) self.assertEqual(self.mock_mailer.call_count, 2) self.key = re.search(r'http://.+/confirm/(?P<key>[\S]+)/', self.mock_mailer.call_args[0][1]).group("key") confirm_comment_url(self.key) self.assertEqual(self.mock_mailer.call_count, 3) self.assertTrue(self.mock_mailer.call_args[0][3] == ["*****@*****.**"]) self.assertTrue(self.mock_mailer.call_args[0][1].find( "There is a new comment following up yours.") > -1)
def setUp(self): patcher = patch('django_comments_tree.views.comments.send_mail') self.mock_mailer = patcher.start() self.article = Article.objects.create( title="October", slug="october", body="What I did on October...") self.form = get_form()(self.article) self.factory = RequestFactory() self.user = AnonymousUser()
def test_notify_followers_dupes(self): # first of all confirm Bob's comment otherwise it doesn't reach DB confirm_comment_url(self.key) # then put in play pull-request-15's assert... # https://github.com/sharpertool/django-comments-tree/pull/15 diary = Diary.objects.create( body='Lorem ipsum', allow_comments=True ) self.assertEqual(diary.pk, self.article.pk) self.form = get_form()(diary) data = {"name": "Charlie", "email": "*****@*****.**", "followup": True, "reply_to": 0, "level": 1, "order": 1, "comment": "Es war einmal eine kleine..."} data.update(self.form.initial) response = post_diary_comment(data, diary_entry=diary) self.assertEqual(response.status_code, 302) self.assertTrue(response.url.startswith('/comments/posted/?c=')) self.key = str(re.search(r'http://.+/confirm/(?P<key>[\S]+)/', self.mock_mailer.call_args[0][1]).group("key")) # 1) confirmation for Bob (sent in `setUp()`) # 2) confirmation for Charlie self.assertEqual(self.mock_mailer.call_count, 2) response = confirm_comment_url(self.key) self.assertEqual(response.status_code, 302) self.assertTrue(response.url.startswith('/comments/cr/')) self.assertEqual(self.mock_mailer.call_count, 2) self.form = get_form()(self.article) data = {"name": "Alice", "email": "*****@*****.**", "followup": True, "reply_to": 0, "level": 1, "order": 1, "comment": "Es war einmal iene kleine..."} data.update(self.form.initial) response = post_article_comment(data, article=self.article) self.assertEqual(response.status_code, 302) self.assertTrue(response.url.startswith('/comments/posted/?c=')) self.assertEqual(self.mock_mailer.call_count, 3) self.key = re.search(r'http://.+/confirm/(?P<key>[\S]+)/', self.mock_mailer.call_args[0][1]).group("key") confirm_comment_url(self.key) self.assertEqual(self.mock_mailer.call_count, 4) self.assertTrue(self.mock_mailer.call_args[0][3] == ["*****@*****.**"]) self.assertTrue(self.mock_mailer.call_args[0][1].find( "There is a new comment following up yours.") > -1)
def setUp(self): patcher_app1 = patch(send_mail) patcher_app2 = patch('django_comments_tree.views.comments.send_mail') self.mailer_app1 = patcher_app1.start() self.mailer_app2 = patcher_app2.start() self.diary_entry = Diary.objects.create(body="What I did Yesterday...", allow_comments=True, publish=datetime.now() - timedelta(days=5)) self.form = django_comments_tree.get_form()(self.diary_entry)
def setUp(self): # Create an article and send a comment. Test method will chech headers # to see wheter messages has multiparts or not. patcher = patch('django_comments_tree.views.comments.send_mail') self.mock_mailer = patcher.start() self.article = Article.objects.create( title="September", slug="september", body="John's September") self.form = get_form()(self.article) # Bob sends 1st comment to the article with follow-up self.data = {"name": "Bob", "email": "*****@*****.**", "followup": True, "reply_to": 0, "level": 1, "order": 1, "comment": "Nice September you had..."} self.data.update(self.form.initial)
def test_get_comment_create_data(self): # as it's used in django_comments.views.comments data = {"name": "Daniel", "email": "*****@*****.**", "followup": True, "reply_to": 0, "level": 1, "order": 1, "comment": "Es war einmal iene kleine..."} data.update(self.form.initial) form = django_comments_tree.get_form()(self.article, data) self.assertTrue(self.form.security_errors() == {}) self.assertTrue(self.form.errors == {}) comment = form.get_comment_object() # it does have the new field 'followup' self.assertTrue("followup" in comment)
def setUp(self): diary_entry = Diary.objects.create(body="What I did on October...", allow_comments=True, publish=datetime.now()) form = django_comments_tree.get_form()(diary_entry) self.user = User.objects.create_user("bob", "*****@*****.**", "pwd") data = { "name": "Bob", "email": "*****@*****.**", "followup": True, "reply_to": 0, "level": 1, "order": 1, "comment": "Es war einmal eine kleine..." } data.update(form.initial) post_diary_comment(data, diary_entry, auth_user=self.user)
def setUp(self): patcher = patch('django_comments_tree.views.comments.send_mail') self.mock_mailer = patcher.start() # Create random string so that it's harder for zlib to compress content = ''.join(random.choice(string.printable) for _ in range(6096)) self.article = Article.objects.create(title="September", slug="september", body="In September..." + content) self.form = get_form()(self.article) data = {"name": "Bob", "email": "*****@*****.**", "followup": True, "reply_to": 0, "level": 1, "order": 1, "comment": "Es war einmal iene kleine..."} data.update(self.form.initial) response = post_article_comment(data, self.article) self.assertTrue(self.mock_mailer.call_count == 1) self.key = str(re.search(r'http://.+/confirm/(?P<key>[\S]+)/', self.mock_mailer.call_args[0][1]).group("key")) self.addCleanup(patcher.stop)
def test_no_notification_for_same_user_email(self): # test that a follow-up user_email don't get a notification when # sending another email to the thread self.assertEqual(self.mock_mailer.call_count, 1) confirm_comment_url(self.key) # confirm Bob's comment # no comment followers yet: self.assertEqual(self.mock_mailer.call_count, 1) # send Bob's 2nd comment self.form = get_form()(self.article) data = {"name": "Alice", "email": "*****@*****.**", "followup": True, "reply_to": 0, "level": 1, "order": 1, "comment": "Bob's comment he shouldn't get notified about"} data.update(self.form.initial) response = post_article_comment(data, self.article) self.assertEqual(self.mock_mailer.call_count, 2) self.key = re.search(r'http://.+/confirm/(?P<key>[\S]+)/', self.mock_mailer.call_args[0][1]).group("key") confirm_comment_url(self.key) self.assertEqual(self.mock_mailer.call_count, 2)
def setUp(self): # Creates an article and send two comments to the article with follow-up # notifications. First comment doesn't have to send any notification. # Second comment has to send one notification (to Bob). self.factory = RequestFactory() patcher = patch('django_comments_tree.views.comments.send_mail') self.mock_mailer = patcher.start() self.article = Article.objects.create( title="September", slug="september", body="John's September") self.form = get_form()(self.article) # Bob sends 1st comment to the article with follow-up data = {"name": "Bob", "email": "*****@*****.**", "followup": True, "reply_to": 0, "level": 1, "order": 1, "comment": "Nice September you had..."} data.update(self.form.initial) response = post_article_comment(data, self.article) self.assertEqual(response.status_code, 302) self.assertTrue(response.url.startswith('/comments/posted/?c=')) self.assertTrue(self.mock_mailer.call_count == 1) bobkey = str(re.search(r'http://.+/confirm/(?P<key>[\S]+)/', self.mock_mailer.call_args[0][1]).group("key")) confirm_comment_url(bobkey) # confirm Bob's comment # Alice sends 2nd comment to the article with follow-up data = {"name": "Alice", "email": "*****@*****.**", "followup": True, "reply_to": 1, "level": 1, "order": 1, "comment": "Yeah, great photos"} data.update(self.form.initial) response = post_article_comment(data, self.article) self.assertEqual(response.status_code, 302) self.assertTrue(response.url.startswith('/comments/posted/?c=')) self.assertTrue(self.mock_mailer.call_count == 2) alicekey = str(re.search(r'http://.+/confirm/(?P<key>[\S]+)/', self.mock_mailer.call_args[0][1]).group("key")) confirm_comment_url(alicekey) # confirm Alice's comment # Bob receives a follow-up notification self.assertTrue(self.mock_mailer.call_count == 3) self.bobs_mutekey = str(re.search( r'http://.+/mute/(?P<key>[\S]+)/', self.mock_mailer.call_args[0][1]).group("key")) self.addCleanup(patcher.stop)
def reply(request, cid): try: comment = TreeComment.objects.get(pk=cid) if not comment.allow_thread(): raise MaxThreadLevelExceededException(comment) except MaxThreadLevelExceededException as exc: return HttpResponseForbidden(exc) except TreeComment.DoesNotExist as exc: raise Http404(exc) form = get_form()(comment.content_object, comment=comment) next = request.GET.get("next", reverse("comments-tree-sent")) template_arg = [ "django_comments_tree/%s/%s/reply.html" % ( comment.content_type.app_label, comment.content_type.model), "django_comments_tree/%s/reply.html" % ( comment.content_type.app_label,), "django_comments_tree/reply.html" ] return render(request, template_arg, {"comment": comment, "form": form, "cid": cid, "next": next})
def validate(self, data): ctype = data.get("content_type") object_id = data.get("object_id") if ctype is None or object_id is None: return serializers.ValidationError("Missing content_type or " "object_id field.") try: model = apps.get_model(*ctype.split(".", 1)) target = model._default_manager.get(pk=object_id) except TypeError: return serializers.ValidationError( "Invalid content_type value: %r" % escape(ctype)) except AttributeError: return serializers.ValidationError( "The given content-type %r does " "not resolve to a valid model." % escape(ctype)) except model.ObjectDoesNotExist: return serializers.ValidationError( "No object matching content-type %r and object ID %r exists." % (escape(ctype), escape(object_id))) except (ValueError, serializers.ValidationError) as e: return serializers.ValidationError( "Attempting go get content-type %r and object ID %r exists " "raised %s" % (escape(ctype), escape(object_id), e.__class__.__name__)) self.form = get_form()(target, data=data) # Check security information if self.form.security_errors(): return serializers.ValidationError( "The comment form failed security verification: %s" % escape(str(self.form.security_errors()))) if self.form.errors: return serializers.ValidationError(self.form.errors) return data
def setUp(self): patcher = patch('django_comments_tree.views.comments.send_mail') self.mock_mailer = patcher.start() self.article = Article.objects.create( title="October", slug="october", body="What I did on October...") self.form = django_comments_tree.get_form()(self.article)
def get_form(self, context): obj = self.get_object(context) if obj: return django_comments_tree.get_form()(obj) else: return None
def setUp(self): self.article = Article.objects.create(title="September", slug="september", body="What I did on September...") self.form = django_comments_tree.get_form()(self.article)
def test_get_form(self): # check function django_comments_tree.get_form retrieves the due class self.assertTrue(django_comments_tree.get_form() == TreeCommentForm)
def post(self, request, next=None, using=None): """ Post a comment. HTTP POST is required. If ``POST['submit'] == "preview"`` or if there are errors a preview template, ``comments/preview.html``, will be rendered. """ # Fill out some initial data fields from an authenticated user, if present data = request.POST.copy() if request.user.is_authenticated: if not data.get('name', ''): data["name"] = request.user.get_full_name() or request.user.get_username() if not data.get('email', ''): data["email"] = request.user.email # Look up the object we're trying to comment about ctype = data.get("content_type") object_id = data.get("object_id") if ctype is None or object_id is None: return CommentPostBadRequest("Missing content_type or object_id field.") try: model = apps.get_model(*ctype.split(".", 1)) target = model._default_manager.using(using).get(pk=object_id) except TypeError: return CommentPostBadRequest( "Invalid content_type value: %r" % escape(ctype)) except AttributeError: return CommentPostBadRequest( "The given content-type %r does not resolve to a valid model." % escape(ctype)) except ObjectDoesNotExist: return CommentPostBadRequest( "No object matching content-type %r and object PK %r exists." % ( escape(ctype), escape(object_id))) except (ValueError, ValidationError) as e: return CommentPostBadRequest( "Attempting go get content-type %r and object PK %r exists raised %s" % ( escape(ctype), escape(object_id), e.__class__.__name__)) # Do we want to preview the comment? preview = "preview" in data # Construct the comment form form = get_form()(target, data=data) # Check security information if form.security_errors(): return CommentPostBadRequest( f"The comment form failed security verification:" f" {escape(str(form.security_errors()))}") # If there are errors or if we requested a preview show the comment if form.errors or preview: app_lbl = model._meta.app_label nm = model._meta.model_name template_list = [ # These first two exist for purely historical reasons. # Django v1.0 and v1.1 allowed the underscore format for # preview templates, so we have to preserve that format. f"comments/{app_lbl}_{nm}_preview.html", f"comments/{app_lbl}_preview.html", # Now the usual directory based template hierarchy. f"comments/{app_lbl}/{nm}/preview.html", f"comments/{app_lbl}/preview.html", "comments/preview.html", ] return render(request, template_list, { "comment": form.data.get("comment", ""), "form": form, "next": data.get("next", next), }, ) # Otherwise create the comment comment = form.get_comment_object(site_id=get_current_site(request).id) comment.ip_address = request.META.get("REMOTE_ADDR", None) or None if request.user.is_authenticated: comment.user = request.user # Signal that the comment is about to be saved responses = signals.comment_will_be_posted.send( sender=comment.__class__, comment=comment, request=request ) for (receiver, response) in responses: if response is False: return CommentPostBadRequest( "comment_will_be_posted receiver %r killed the comment" % receiver.__name__) # Save the comment and signal that it was saved comment.save() signals.comment_was_posted.send( sender=comment.__class__, comment=comment, request=request ) return next_redirect(request, fallback=next or 'comments-comment-done', c=comment._get_pk_val())