Skip to content

Commit

Permalink
Merge e3d3fa5 into 0aa6c09
Browse files Browse the repository at this point in the history
  • Loading branch information
nathanbegbie committed Mar 8, 2017
2 parents 0aa6c09 + e3d3fa5 commit 9ae5cd6
Show file tree
Hide file tree
Showing 14 changed files with 223 additions and 4 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ install:
script:
- flake8 molo
- molo scaffold testapp --include molo.commenting ^commenting/
- cp molo/commenting/templates/test_templates/main.html testapp/testapp/templates/core/main.html
- flake8 testapp
- cp test_settings.py testapp/testapp/settings/local.py
- pip install -e testapp
Expand Down
27 changes: 26 additions & 1 deletion molo/commenting/models.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
from django_comments.models import Comment, COMMENT_MAX_LENGTH
from django_comments.models import CommentFlag
from django.dispatch import receiver
from django_comments.signals import comment_was_flagged
from django_comments.signals import (
comment_was_flagged,
comment_was_posted,
)
from django.conf import settings
from django.db import models

from mptt.models import MPTTModel, TreeForeignKey

from notifications.signals import notify


class MoloComment(MPTTModel, Comment):
"""
Expand Down Expand Up @@ -48,6 +53,26 @@ def remove_comment_if_flag_limit(sender, comment, flag, created, **kwargs):
comment.save()


@receiver(comment_was_posted)
def create_notification_for_comment_reply(sender, comment, request, **kwargs):
# check if comment is a reply
if comment.get_ancestors():

user_replying = request.user
parent_comment = comment.get_ancestors().first()
user_being_replied_to = parent_comment.user
article = parent_comment.content_object

notify.send(
user_replying,
recipient=user_being_replied_to,
verb=u'replied',
action_object=comment,
description=comment.comment,
target=article
)


class CannedResponse(models.Model):
response_header = models.CharField(max_length=500, blank=False)
response = models.TextField(max_length=COMMENT_MAX_LENGTH, blank=False)
Expand Down
1 change: 0 additions & 1 deletion molo/commenting/templates/comments/comment_done.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{% extends "base.html" %}
{% load wagtailcore_tags wagtailimages_tags comments mptt_tags molo_commenting_tags i18n %}

{% block content %}
Expand Down
1 change: 0 additions & 1 deletion molo/commenting/templates/comments/comments.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{% extends "base.html" %}
{% load wagtailcore_tags wagtailimages_tags comments molo_commenting_tags i18n mptt_tags %}

{% block content %}
Expand Down
28 changes: 28 additions & 0 deletions molo/commenting/templates/notifications/notice.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{% load wagtailcore_tags i18n %}
<div class="notification-block">
<p>---------------------</p>
<p>
{% with notice.target as article %}
{% with notice.action_object as comment %}
{% if comment.user_name.lower == 'anonymous' %}
{{comment.user_name}}
{% else %}
{% if not comment.user.profile.alias %}
{% trans "Anonymous" %}
{% else %}
{{comment.user.profile.alias}}
{% endif %}
{% endif %}

{% trans "replied to your comment on" %}
<a href="{% pageurl article %}">{{ article.title }}</a>
{{ notice.timesince }} {% trans "ago" %}
{% endwith %}
{% endwith %}
</p>
<h2>Your Comment:</h2>
<p>{{ notice.action_object.parent.comment }}</p>

<h2>Their Reply:</h2>
<p>{{ notice.action_object.comment }}</p>
</div>
25 changes: 25 additions & 0 deletions molo/commenting/templates/notifications/reply_list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{% extends "base.html" %}
{% load i18n %}

{% block content %}

<h1>{% trans "You have" %} {{ number_unread_notifications }} {% trans "unread replies" %}</h1>

{% if unread_notifications %}
<h2><b>Unread</b></h2>
<ul class="notifications unread_notification">
{% for notice in unread_notifications %}
{% include 'notifications/notice.html' %}
{% endfor %}
</ul>
{% endif %}

{% if read_notifications %}
<h2><b>Read</b></h2>
<ul class="notifications">
{% for notice in read_notifications %}
{% include 'notifications/notice.html' %}
{% endfor %}
</ul>
{% endif %}
{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{% load i18n %}
<div class="notifications-list__item">
{% if user.is_authenticated and number_unread_notifications > 0 %}
<a href="{% url 'molo.commenting:reply_list' %}">
<div style="background-color: orange;width:100%">
{% trans "Unread replies:" %} {{ number_unread_notifications }}
</div>
</a>
{% endif %}
</div>
6 changes: 6 additions & 0 deletions molo/commenting/templates/test_templates/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{% extends "base.html" %}
{% load molo_commenting_tags %}

{% block content %}
{% display_unread_notifications %}
{% endblock %}
17 changes: 17 additions & 0 deletions molo/commenting/templatetags/molo_commenting_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,23 @@ def is_in_group(user, group_name):
return user.groups.filter(name__exact=group_name).exists()


@register.inclusion_tag(
'notifications/tags/notification_banner.html',
takes_context=True)
def display_unread_notifications(context):
user = context['request'].user

number_unread_notifications = 0

if user.is_authenticated():
number_unread_notifications = len(user.notifications.unread())

return {
'user': user,
'number_unread_notifications': number_unread_notifications,
}


register.filter('is_in_group', is_in_group)
register.tag('get_molo_comments', get_molo_comments)
register.tag('get_comments_content_object', get_comments_content_object)
88 changes: 88 additions & 0 deletions molo/commenting/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@
from molo.core.models import ArticlePage
from molo.core.tests.base import MoloTestCaseMixin

from notifications.models import Notification

urlpatterns = patterns(
'',
url(r'^commenting/',
include('molo.commenting.urls', namespace='molo.commenting')),
url(r'', include('django_comments.urls')),
url(r'', include('molo.core.urls')),
url(r'', include('wagtail.wagtailcore.urls')),
)


Expand Down Expand Up @@ -265,3 +269,87 @@ def test_view_replies_report(self):
self.assertTrue('report' in crow.prettify())
self.assertTrue(reply.comment in replyrow.prettify())
self.assertFalse('report' in replyrow.prettify())


@override_settings(ROOT_URLCONF='molo.commenting.tests.test_views')
class ViewNotificationsRepliesOnCommentsTest(TestCase, MoloTestCaseMixin):

def setUp(self):
# Creates main page
self.mk_main()
self.user = User.objects.create_user(
'test', 'test@example.org', 'test')
self.article = ArticlePage.objects.create(
title='article 1', depth=1,
subtitle='article 1 subtitle',
slug='article-1', path=[1])

self.client = Client()
self.client.login(username='test', password='test')

def create_comment(self, comment, parent=None):
return MoloComment.objects.create(
content_type=ContentType.objects.get_for_model(self.article),
object_pk=self.article.pk,
content_object=self.article,
site=Site.objects.get_current(),
user=self.user,
comment=comment,
parent=parent,
submit_date=datetime.now())

def test_notification_reply_list(self):
self.client = Client()
self.client.login(username='test', password='test')

data = MoloCommentForm(self.user, {}).generate_security_data()
data.update({
'name': 'the supplied name',
'comment': 'Foo',
})
self.client.post(
reverse('molo.commenting:molo-comments-post'), data)
[comment] = MoloComment.objects.filter(user=self.user)
self.assertEqual(comment.comment, 'Foo')
self.assertEqual(comment.user_name, 'the supplied name')

response = self.client.get('/')
self.assertEqual(response.status_code, 200)
self.assertNotContains(response, 'Unread replies: 0')

data = MoloCommentForm(self.user, {}).generate_security_data()
data.update({
'name': 'the supplied name',
'comment': 'Foo reply',
'parent': comment.pk
})
self.client.post(
reverse('molo.commenting:molo-comments-post'), data)
self.assertEqual(Notification.objects.unread().count(), 1)

response = self.client.get('/')
self.assertEqual(response.status_code, 200)
html = BeautifulSoup(response.content, 'html.parser')
[ntfy] = html.find_all("div", class_='notifications-list__item')
self.assertEqual(ntfy.find("div").get_text().strip(),
'Unread replies: 1')

# Unread notifications
response = self.client.get(
reverse('molo.commenting:reply_list'))
self.assertContains(response, 'You have 1 unread replies')
self.assertContains(response, 'Unread')
n = Notification.objects.filter(recipient=self.user).first()
n.mark_as_read()
self.assertEqual(Notification.objects.unread().count(), 0)

response = self.client.get('/')
self.assertEqual(response.status_code, 200)
self.assertNotContains(response, 'Unread replies: 0')

# Read notifications
response = self.client.get(
reverse('molo.commenting:reply_list'))
self.assertEqual(Notification.objects.read().count(), 1)
self.assertContains(response, 'You have 0 unread replies')
self.assertContains(response, 'Read')
3 changes: 2 additions & 1 deletion molo/commenting/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@
r'molo/(?P<page_id>\d+)/comments/$',
views.view_more_article_comments,
name='more-comments'),

url(r'molo/replies/$',
views.reply_list, name='reply_list'),
)
18 changes: 18 additions & 0 deletions molo/commenting/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,21 @@ def get(self, request, parent_comment_pk):
'form': form,
'comment': comment,
})


@login_required
def reply_list(request):
unread_notifications = list(request.user.notifications.unread())
read_notifications = list(request.user.notifications.read())

for notification in unread_notifications:
notification.unread = False
notification.save()

number_unread_notifications = len(unread_notifications)

return render(request, 'notifications/reply_list.html', {
'read_notifications': read_notifications,
'unread_notifications': unread_notifications,
'number_unread_notifications': number_unread_notifications,
})
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ django-contrib-comments==1.7.1
django-mptt==0.8.5
django-import-export
django-daterange-filter
django-notifications-hq
1 change: 1 addition & 0 deletions test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

INSTALLED_APPS = INSTALLED_APPS + [
'django_comments',
'notifications',
]

COMMENTS_APP = 'molo.commenting'
Expand Down

0 comments on commit 9ae5cd6

Please sign in to comment.