Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Découple le module de forum du module de notification #5976

Merged
8 changes: 4 additions & 4 deletions zds/forum/commons.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from django.contrib.auth.models import User

from zds.forum.models import Forum, Post, TopicRead
from zds.notification import signals
from zds.forum import signals
from zds.notification.models import TopicAnswerSubscription, Notification, NewTopicSubscription
from zds.utils.models import Alert, CommentEdit, get_hat_from_request

Expand Down Expand Up @@ -75,7 +75,7 @@ def perform_move(self):
# Save topic to update update_index_date
self.object.save()

signals.edit_content.send(sender=self.object.__class__, instance=self.object, action="move")
signals.topic_moved.send(sender=self.object.__class__, topic=self.object)
message = _("Le sujet « {0} » a bien été déplacé dans « {1} ».").format(self.object.title, forum.title)
messages.success(self.request, message)
else:
Expand Down Expand Up @@ -110,7 +110,7 @@ def perform_hide_message(request, post, user, data):

messages.success(request, _("Le message est désormais masqué."))
for user in Notification.objects.get_users_for_unread_notification_on(post):
signals.content_read.send(sender=post.topic.__class__, instance=post.topic, user=user)
signals.topic_read.send(sender=post.topic.__class__, instance=post.topic, user=user)
else:
raise PermissionDenied

Expand Down Expand Up @@ -162,7 +162,7 @@ def perform_unread_message(post, user):
elif topic_read:
topic_read.delete()

signals.answer_unread.send(sender=post.topic.__class__, instance=post, user=user)
signals.post_unread.send(sender=post.__class__, post=post, user=user)

@staticmethod
def perform_edit_post(request, post, user, text):
Expand Down
6 changes: 3 additions & 3 deletions zds/forum/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from elasticsearch_dsl.field import Text, Keyword, Integer, Boolean, Float, Date

from zds.forum.managers import TopicManager, ForumManager, PostManager, TopicReadManager
from zds.notification import signals
from zds.forum import signals
from zds.searchv2.models import AbstractESDjangoIndexable, delete_document_in_elasticsearch, ESIndexManager
from zds.utils import get_current_user, slugify
from zds.utils.models import Comment, Tag
Expand Down Expand Up @@ -295,7 +295,7 @@ def add_tags(self, tag_collection):
logging.getLogger(__name__).warning(e)

self.save()
signals.edit_content.send(sender=self.__class__, instance=self, action="edit_tags_and_title")
signals.topic_edited.send(sender=self.__class__, topic=self)

def last_read_post(self):
"""
Expand Down Expand Up @@ -624,4 +624,4 @@ def mark_read(topic, user=None):
else:
current_topic_read.post = topic.last_message
current_topic_read.save()
signals.content_read.send(sender=topic.__class__, instance=topic, user=user)
signals.topic_read.send(sender=topic.__class__, instance=topic, user=user)
7 changes: 7 additions & 0 deletions zds/forum/signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.dispatch import Signal

topic_moved = Signal(providing_args=["topic"])
topic_edited = Signal(providing_args=["topic"])
topic_read = Signal(providing_args=["instance", "user"])
post_read = Signal(providing_args=["instance", "user"])
post_unread = Signal(providing_args=["post", "user"])
47 changes: 34 additions & 13 deletions zds/forum/tests/tests_views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from datetime import datetime
from unittest.mock import patch

from django.conf import settings
from django.contrib.auth.models import User, Group
Expand Down Expand Up @@ -645,7 +646,8 @@ def test_success_edit_topic_sticky_by_staff(self):
self.assertEqual(302, response.status_code)
self.assertFalse(Topic.objects.get(pk=topic.pk).is_sticky)

def test_failure_edit_topic_move_by_user(self):
@patch("zds.forum.signals.topic_moved")
def test_failure_edit_topic_move_by_user(self, topic_moved):
profile = ProfileFactory()

another_profile = ProfileFactory()
Expand All @@ -656,9 +658,11 @@ def test_failure_edit_topic_move_by_user(self):
data = {"move": "", "topic": topic.pk}
response = self.client.post(reverse("topic-edit"), data, follow=False)

self.assertEqual(topic_moved.send.call_count, 0)
self.assertEqual(403, response.status_code)

def test_failure_edit_topic_move_with_wrong_forum_pk_by_staff(self):
@patch("zds.forum.signals.topic_moved")
def test_failure_edit_topic_move_with_wrong_forum_pk_by_staff(self, topic_moved):
staff = StaffProfileFactory()

profile = ProfileFactory()
Expand All @@ -669,9 +673,11 @@ def test_failure_edit_topic_move_with_wrong_forum_pk_by_staff(self):
data = {"move": "", "forum": "abc", "topic": topic.pk}
response = self.client.post(reverse("topic-edit"), data, follow=False)

self.assertEqual(topic_moved.send.call_count, 0)
self.assertEqual(404, response.status_code)

def test_failure_edit_topic_move_with_a_forum_not_found_by_staff(self):
@patch("zds.forum.signals.topic_moved")
def test_failure_edit_topic_move_with_a_forum_not_found_by_staff(self, topic_moved):
staff = StaffProfileFactory()

profile = ProfileFactory()
Expand All @@ -682,9 +688,11 @@ def test_failure_edit_topic_move_with_a_forum_not_found_by_staff(self):
data = {"move": "", "forum": 99999, "topic": topic.pk}
response = self.client.post(reverse("topic-edit"), data, follow=False)

self.assertEqual(topic_moved.send.call_count, 0)
self.assertEqual(404, response.status_code)

def test_success_edit_topic_move_by_staff(self):
@patch("zds.forum.signals.topic_moved")
def test_success_edit_topic_move_by_staff(self, topic_moved):
staff = StaffProfileFactory()

profile = ProfileFactory()
Expand All @@ -697,6 +705,7 @@ def test_success_edit_topic_move_by_staff(self):
data = {"move": "", "forum": another_forum.pk, "topic": topic.pk}
response = self.client.post(reverse("topic-edit"), data, follow=False)

self.assertEqual(topic_moved.send.call_count, 1)
self.assertEqual(302, response.status_code)

def test_failure_edit_topic_not_author_and_not_staff(self):
Expand Down Expand Up @@ -1903,17 +1912,20 @@ def test_hide(self):


class PostUnreadTest(TestCase):
def test_failure_post_unread_require_method_get(self):
@patch("zds.forum.signals.post_unread")
def test_failure_post_unread_require_method_get(self, post_unread):
response = self.client.post(reverse("post-unread"), follow=False)

self.assertEqual(post_unread.send.call_count, 0)
self.assertEqual(405, response.status_code)

def test_failure_post_unread_with_client_unauthenticated(self):
@patch("zds.forum.signals.post_unread")
def test_failure_post_unread_with_client_unauthenticated(self, post_unread):
response = self.client.get(reverse("post-unread"), follow=False)

self.assertEqual(post_unread.send.call_count, 0)
self.assertEqual(302, response.status_code)

def test_failure_post_unread_with_sanctioned_user(self):
@patch("zds.forum.signals.post_unread")
def test_failure_post_unread_with_sanctioned_user(self, post_unread):
profile = ProfileFactory()
profile.can_read = False
profile.can_write = False
Expand All @@ -1922,25 +1934,31 @@ def test_failure_post_unread_with_sanctioned_user(self):
self.assertTrue(self.client.login(username=profile.user.username, password="hostel77"))
response = self.client.get(reverse("post-unread"))

self.assertEqual(post_unread.send.call_count, 0)
self.assertEqual(403, response.status_code)

def test_failure_post_unread_with_wrong_topic_pk(self):
@patch("zds.forum.signals.post_unread")
def test_failure_post_unread_with_wrong_topic_pk(self, post_unread):
profile = ProfileFactory()

self.assertTrue(self.client.login(username=profile.user.username, password="hostel77"))
response = self.client.get(reverse("post-unread") + "?message=abc", follow=False)

self.assertEqual(post_unread.send.call_count, 0)
self.assertEqual(404, response.status_code)

def test_failure_post_unread_with_a_topic_not_found(self):
@patch("zds.forum.signals.post_unread")
def test_failure_post_unread_with_a_topic_not_found(self, post_unread):
profile = ProfileFactory()

self.assertTrue(self.client.login(username=profile.user.username, password="hostel77"))
response = self.client.get(reverse("post-unread") + "?message=99999", follow=False)

self.assertEqual(post_unread.send.call_count, 0)
self.assertEqual(404, response.status_code)

def test_failure_post_unread_of_a_forum_we_cannot_read(self):
@patch("zds.forum.signals.post_unread")
def test_failure_post_unread_of_a_forum_we_cannot_read(self, post_unread):
group = Group.objects.create(name="DummyGroup_1")

profile = ProfileFactory()
Expand All @@ -1950,9 +1968,11 @@ def test_failure_post_unread_of_a_forum_we_cannot_read(self):
self.assertTrue(self.client.login(username=profile.user.username, password="hostel77"))
response = self.client.get(reverse("post-unread") + "?message={}".format(topic.last_message.pk))

self.assertEqual(post_unread.send.call_count, 0)
self.assertEqual(403, response.status_code)

def test_success_post_unread(self):
@patch("zds.forum.signals.post_unread")
def test_success_post_unread(self, post_unread):
profile = ProfileFactory()
_, forum = create_category_and_forum()
topic = create_topic_in_forum(forum, profile)
Expand All @@ -1962,6 +1982,7 @@ def test_success_post_unread(self):
self.assertTrue(self.client.login(username=profile.user.username, password="hostel77"))
response = self.client.get(reverse("post-unread") + "?message={}".format(post.pk), follow=False)

self.assertEqual(post_unread.send.call_count, 1)
self.assertEqual(302, response.status_code)


Expand Down
4 changes: 2 additions & 2 deletions zds/forum/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from zds.forum.models import ForumCategory, Forum, Topic, Post, is_read, mark_read, TopicRead
from zds.member.decorator import can_write_and_read_now
from zds.member.models import user_readable_forums
from zds.notification import signals
from zds.forum import signals
from zds.notification.models import NewTopicSubscription, TopicAnswerSubscription
from zds.featured.mixins import FeatureableMixin
from zds.utils import slugify
Expand Down Expand Up @@ -214,7 +214,7 @@ def get_context_data(self, **kwargs):

if self.request.user.is_authenticated:
for post in posts:
signals.content_read.send(sender=post.__class__, instance=post, user=self.request.user)
signals.post_read.send(sender=post.__class__, instance=post, user=self.request.user)
if not is_read(self.object):
mark_read(self.object)
return context
Expand Down
47 changes: 20 additions & 27 deletions zds/notification/receivers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from django.dispatch import receiver

from zds.forum.models import Topic, Post, Forum
import zds.forum.signals as forum_signals
from zds.mp.models import PrivateTopic, PrivatePost
import zds.mp.signals as mp_signals
from zds.notification.models import (
Expand Down Expand Up @@ -84,20 +85,19 @@ def wrapper(*args, **kwargs):
return wrapper


@receiver(notification_signals.answer_unread, sender=Topic)
def unread_topic_event(sender, *, user, instance, **__):
@receiver(forum_signals.post_unread, sender=Post)
def unread_topic_event(sender, *, user, post, **__):
"""
Sends a notification to the user, without sending an email

:param instance: the answer being marked as unread
:param user: user marking the answer as unread

Send a notification to the user, without sending an email.
:param post: the post being marked as unread
:param user: the user marking the post as unread
"""
subscription = TopicAnswerSubscription.objects.get_existing(user, instance.topic, is_active=True)
subscription = TopicAnswerSubscription.objects.get_existing(user, post.topic, is_active=True)
if subscription:
subscription.send_notification(content=instance, sender=instance.author, send_email=False)
subscription.send_notification(content=post, sender=post.author, send_email=False)


@receiver(forum_signals.topic_read, sender=Topic)
@receiver(notification_signals.content_read, sender=Topic)
def mark_topic_notifications_read(sender, *, instance, user, **__):
"""
Expand Down Expand Up @@ -226,7 +226,7 @@ def clean_subscriptions(sender, *, topic, **__):


@receiver(notification_signals.content_read, sender=ContentReaction)
@receiver(notification_signals.content_read, sender=Post)
@receiver(forum_signals.post_read, sender=Post)
def mark_comment_read(sender, *, instance, user, **__):
comment = instance

Expand All @@ -235,28 +235,21 @@ def mark_comment_read(sender, *, instance, user, **__):
subscription.mark_notification_read(comment)


@receiver(notification_signals.edit_content, sender=Topic)
def edit_topic_event(sender, *, action, instance, **kwargs):
"""
:param kwargs: contains
- instance: the topic edited.
- action: action of the edit.
"""
topic = instance
@receiver(forum_signals.topic_moved, sender=Topic)
def moved_topic_event(sender, *, topic, **kwargs):
topic_content_type = ContentType.objects.get_for_model(topic)
_handle_private_forum_moving(topic, topic_content_type, ContentType.objects.get_for_model(topic.last_message))

if action == "move":

_handle_private_forum_moving(topic, topic_content_type, ContentType.objects.get_for_model(topic.last_message))

elif action == "edit_tags_and_title":
topic = instance
@receiver(forum_signals.topic_edited, sender=Topic)
def edit_topic_event(sender, *, topic, **kwargs):
topic_content_type = ContentType.objects.get_for_model(topic)

# Update notification as dead if it was triggered by a deleted tag
tag_content_type = _handle_deleted_tags(topic, topic_content_type)
# Update notification as dead if it was triggered by a deleted tag
tag_content_type = _handle_deleted_tags(topic, topic_content_type)

# Add notification of new topic for the subscription on the new tags
_handle_added_tags(tag_content_type, topic)
# Add notification of new topic for the subscription on the new tags
_handle_added_tags(tag_content_type, topic)


def _handle_added_tags(tag_content_type, topic):
Expand Down