Repository: zestedesavoir/zds-site

Issue:
[v18] J'ai perdu mes sujets suivis
Version : 18
OS Windows
Navigateur Firefox

Alors qu'une synchro a été faite entre la prod et la beta, je ne retrouve plus mes sujets suivis dans la page https://beta.zestedesavoir.com/forums/ comme on peut le voir sur la capture ci-dessous (il ne me reste plus qu'un sujet suivis au lieu de beaucoup plus)

![suivis](https://cloud.githubusercontent.com/assets/6066015/14254805/a75c8ac6-fa91-11e5-9852-d5dc2d60547b.PNG)



Discussion:
Je confirme le bug chez moi aussi. C'est étonnant, c'était un cas testé en local. Je regarde ça dès que possible.

@GerardPaligot des nouvelles sur ce ticket ? Vu qu'il empêche de tester une des grosses nouveautés, j'aimerais qu'il soit corrigé pour pouvoir demander à tout le monde de tester sur la bêta.

Le bug est identifié. Je bosse dessus.

Bien, PR done.

Du coup, on doit pouvoir fermer ici. @GerardPaligot 

Je réouvre cet issue, car autant j'ai récupéré certains sujets suivis, autant il y en a qui ne sont pas là dans dans la sidebar des sujets suivis. Il suffit d'aller sur ce lien : https://beta.zestedesavoir.com/forums/notifications/ et voir la différence entre les sidebar et le reste des notifs

Ouais. Pour information, le bug n'est plus le même. Les sujets sont bien suivis mais la liste des sujets suivis retournés ne sont pas les bons. A mon avis, le bug est semblable à celui de ta dernière ici (à savoir, https://github.com/zestedesavoir/zds-site/issues/3536).


Resolving patch:
diff --git a/zds/notification/managers.py b/zds/notification/managers.py
--- a/zds/notification/managers.py
+++ b/zds/notification/managers.py
@@ -2,6 +2,8 @@
 from django.contrib.contenttypes.models import ContentType
 from django.core.exceptions import ObjectDoesNotExist
 from django.db import models
+
+from zds.forum.models import Topic
 from zds.utils import get_current_user
 
 
@@ -114,19 +116,6 @@ def get_subscribers(self, content_object, only_by_email=False):
 
         return [subscription.user for subscription in subscription_list]
 
-    def get_objects_followed_by(self, user):
-        """
-        Gets objects followed by the given user.
-
-        :param user: concerned user.
-        :type user: django.contrib.auth.models.User
-        :return: All objects followed by given user.
-        """
-        subscription_list = self.filter(user=user, is_active=True) \
-            .order_by('last_notification__pubdate')
-
-        return [subscription.content_object for subscription in subscription_list]
-
     def toggle_follow(self, content_object, user=None, by_email=False):
         """
         Toggle following of a resource notifiable for a user.
@@ -158,6 +147,20 @@ class TopicAnswerSubscriptionManager(SubscriptionManager):
     """
     Custom topic answer subscription manager.
     """
+
+    def get_objects_followed_by(self, user):
+        """
+        Gets objects followed by the given user.
+
+        :param user: concerned user.
+        :type user: django.contrib.auth.models.User
+        :return: All objects followed by given user.
+        """
+        topic_list = self.filter(user=user, is_active=True, content_type=ContentType.objects.get_for_model(Topic)) \
+            .values_list('object_id', flat=True)
+
+        return Topic.objects.filter(id__in=topic_list).order_by('-last_message__pubdate')
+
     def unfollow_and_mark_read_everybody_at(self, topic):
         """
         Deactivate a subscription at a topic and mark read the notification associated if exist.
diff --git a/zds/utils/templatetags/interventions.py b/zds/utils/templatetags/interventions.py
--- a/zds/utils/templatetags/interventions.py
+++ b/zds/utils/templatetags/interventions.py
@@ -65,10 +65,7 @@ def humane_delta(value):
 
 @register.filter('followed_topics')
 def followed_topics(user):
-    topics_followed = TopicAnswerSubscription.objects.filter(user=user,
-                                                             content_type__model='topic',
-                                                             is_active=True)\
-        .order_by('-last_notification__pubdate')[:10]
+    topics_followed = TopicAnswerSubscription.objects.get_objects_followed_by(user)[:10]
     # This period is a map for link a moment (Today, yesterday, this week, this month, etc.) with
     # the number of days for which we can say we're still in the period
     # for exemple, the tuple (2, 1) means for the period "2" corresponding to "Yesterday" according
@@ -76,14 +73,14 @@ def followed_topics(user):
     # Number is use for index for sort map easily
     periods = ((1, 0), (2, 1), (3, 7), (4, 30), (5, 360))
     topics = {}
-    for topic_followed in topics_followed:
+    for topic in topics_followed:
         for period in periods:
-            if topic_followed.content_object.last_message.pubdate.date() \
-                    >= (datetime.now() - timedelta(days=int(period[1]), hours=0, minutes=0, seconds=0)).date():
+            if topic.last_message.pubdate.date() >= \
+                    (datetime.now() - timedelta(days=int(period[1]), hours=0, minutes=0, seconds=0)).date():
                 if period[0] in topics:
-                    topics[period[0]].append(topic_followed.content_object)
+                    topics[period[0]].append(topic)
                 else:
-                    topics[period[0]] = [topic_followed.content_object]
+                    topics[period[0]] = [topic]
                 break
     return topics
 


Test patch:
diff --git a/zds/notification/tests.py b/zds/notification/tests.py
--- a/zds/notification/tests.py
+++ b/zds/notification/tests.py
@@ -9,7 +9,7 @@
 from zds.forum.factories import CategoryFactory, ForumFactory, TopicFactory, PostFactory
 from zds.forum.models import Topic
 from zds.gallery.factories import UserGalleryFactory
-from zds.member.factories import ProfileFactory, StaffProfileFactory
+from zds.member.factories import ProfileFactory, StaffProfileFactory, UserFactory
 from zds.mp.models import mark_read
 from zds.notification import signals
 from zds.notification.models import Notification, TopicAnswerSubscription, ContentReactionAnswerSubscription, \
@@ -214,6 +214,27 @@ def test_hide_post_mark_notification_as_read(self):
         notifications = Notification.objects.filter(object_id=topic.last_message.pk, is_read=True).all()
         self.assertEqual(1, len(notifications))
 
+    def test_topics_followed_by_a_user(self):
+        """
+        Check that we retrieve well topics followed by a user.
+        """
+        user = UserFactory()
+
+        topics_followed = TopicAnswerSubscription.objects.get_objects_followed_by(user)
+        self.assertEqual(0, len(topics_followed))
+
+        first = TopicFactory(forum=self.forum11, author=user)
+        second = TopicFactory(forum=self.forum11, author=user)
+        third = TopicFactory(forum=self.forum11, author=user)
+
+        # Subscribes to all topics.
+        TopicAnswerSubscription.objects.get_or_create_active(user, second)
+        TopicAnswerSubscription.objects.get_or_create_active(user, first)
+        TopicAnswerSubscription.objects.get_or_create_active(user, third)
+
+        topics_followed = TopicAnswerSubscription.objects.get_objects_followed_by(user)
+        self.assertEqual(3, len(topics_followed))
+
 
 class NotificationPublishableContentTest(TestCase):
     def setUp(self):