Repository: zestedesavoir/zds-site

Issue:
Ajout d'un filtre « Sujets sans réponse » dans les forums
Aujourd'hui on peut filtrer les topics par « sujets résolus » ou « sujets non résolus » (http://i.imgur.com/ObP3d0d.png). Un troisième filtre « Sujets sans réponse » peut être assez sympa et très simple à mettre en place.



Discussion:

Resolving patch:
diff --git a/zds/forum/models.py b/zds/forum/models.py
--- a/zds/forum/models.py
+++ b/zds/forum/models.py
@@ -449,21 +449,16 @@ def get_last_topics(user):
     return tops
 
 
-def get_topics(forum_pk, is_sticky, is_solved=None):
-    """ Get topics according to parameters """
-
-    if is_solved is not None:
-        return Topic.objects.filter(
-            forum__pk=forum_pk,
-            is_sticky=is_sticky,
-            is_solved=is_solved).order_by("-last_message__pubdate").prefetch_related(
-            "author",
-            "last_message",
-            "tags").all()
+def get_topics(forum_pk, is_sticky, filter=None):
+    """Get topics according to parameters."""
+
+    if filter == 'solve':
+        topics = Topic.objects.filter(forum__pk=forum_pk, is_sticky=is_sticky, is_solved=True)
+    elif filter == 'unsolve':
+        topics = Topic.objects.filter(forum__pk=forum_pk, is_sticky=is_sticky, is_solved=False)
+    elif filter == 'noanswer':
+        topics = Topic.objects.filter(forum__pk=forum_pk, is_sticky=is_sticky, last_message__position=1)
     else:
-        return Topic.objects.filter(
-            forum__pk=forum_pk,
-            is_sticky=is_sticky).order_by("-last_message__pubdate").prefetch_related(
-            "author",
-            "last_message",
-            "tags").all()
+        topics = Topic.objects.filter(forum__pk=forum_pk, is_sticky=is_sticky)
+
+    return topics.order_by('-last_message__pubdate').prefetch_related('author', 'last_message', 'tags').all()
diff --git a/zds/forum/views.py b/zds/forum/views.py
--- a/zds/forum/views.py
+++ b/zds/forum/views.py
@@ -51,18 +51,12 @@ def details(request, cat_slug, forum_slug):
     forum = get_object_or_404(Forum, slug=forum_slug)
     if not forum.can_read(request.user):
         raise PermissionDenied
-    if "filter" in request.GET:
-        filter = request.GET["filter"]
-        if filter == "solve":
-            sticky_topics = get_topics(forum_pk=forum.pk, is_sticky=True, is_solved=True)
-            topics = get_topics(forum_pk=forum.pk, is_sticky=False, is_solved=True)
-        else:
-            sticky_topics = get_topics(forum_pk=forum.pk, is_sticky=True, is_solved=False)
-            topics = get_topics(forum_pk=forum.pk, is_sticky=False, is_solved=False)
+    if 'filter' in request.GET:
+        filter = request.GET['filter']
     else:
         filter = None
-        sticky_topics = get_topics(forum_pk=forum.pk, is_sticky=True)
-        topics = get_topics(forum_pk=forum.pk, is_sticky=False)
+    sticky_topics = get_topics(forum_pk=forum.pk, is_sticky=True, filter=filter)
+    topics = get_topics(forum_pk=forum.pk, is_sticky=False, filter=filter)
 
     # Paginator
 


Test patch:
diff --git a/zds/forum/tests/tests.py b/zds/forum/tests/tests.py
--- a/zds/forum/tests/tests.py
+++ b/zds/forum/tests/tests.py
@@ -1080,24 +1080,83 @@ def test_url_topic(self):
         self.assertEqual(result.status_code, 200)
 
     def test_filter_topic(self):
-        """Test filters for solved topic or not"""
+        """Test filters for topics"""
+
         ProfileFactory().user
+
         topic = TopicFactory(forum=self.forum11, author=self.user, is_solved=False, is_sticky=False)
+        PostFactory(topic=topic, author=self.user, position=1)
+
         topic_solved = TopicFactory(forum=self.forum11, author=self.user, is_solved=True, is_sticky=False)
+        PostFactory(topic=topic_solved, author=self.user, position=1)
+
         topic_sticky = TopicFactory(forum=self.forum11, author=self.user, is_solved=False, is_sticky=True)
+        PostFactory(topic=topic_sticky, author=self.user, position=1)
+
         topic_solved_sticky = TopicFactory(forum=self.forum11, author=self.user, is_solved=True, is_sticky=True)
+        PostFactory(topic=topic_solved_sticky, author=self.user, position=1)
+
+        # no filter
+
+        # all normal (== not sticky) topics
+        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=False)), 2)
+        self.assertEqual(get_topics(forum_pk=self.forum11.pk, is_sticky=False)[0], topic_solved)
 
-        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=False, is_solved=False)), 1)
-        self.assertEqual(get_topics(forum_pk=self.forum11.pk, is_sticky=False, is_solved=False)[0], topic)
+        # all sticky topics
+        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=True)), 2)
+        self.assertEqual(get_topics(forum_pk=self.forum11.pk, is_sticky=True)[0], topic_solved_sticky)
 
-        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=False, is_solved=True)), 1)
-        self.assertEqual(get_topics(forum_pk=self.forum11.pk, is_sticky=False, is_solved=True)[0], topic_solved)
+        # solved filter
 
-        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=True, is_solved=False)), 1)
-        self.assertEqual(get_topics(forum_pk=self.forum11.pk, is_sticky=True, is_solved=False)[0], topic_sticky)
+        # solved topics
+        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=False, filter='solve')), 1)
+        self.assertEqual(get_topics(forum_pk=self.forum11.pk, is_sticky=False, filter='solve')[0], topic_solved)
 
-        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=True, is_solved=True)), 1)
-        self.assertEqual(get_topics(forum_pk=self.forum11.pk, is_sticky=True, is_solved=True)[0], topic_solved_sticky)
+        # solved sticky topics
+        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=True, filter='solve')), 1)
+        self.assertEqual(get_topics(forum_pk=self.forum11.pk, is_sticky=True, filter='solve')[0], topic_solved_sticky)
 
-        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=False)), 2)
-        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=True)), 2)
+        # unsolved filter
+
+        # unsolved topics
+        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=False, filter='unsolve')), 1)
+        self.assertEqual(get_topics(forum_pk=self.forum11.pk, is_sticky=False, filter='unsolve')[0], topic)
+
+        # unsolved sticky topics
+        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=True, filter='unsolve')), 1)
+        self.assertEqual(get_topics(forum_pk=self.forum11.pk, is_sticky=True, filter='unsolve')[0], topic_sticky)
+
+        # no answer filter
+
+        user1 = ProfileFactory().user
+
+        # create a new topic with answers
+        topic1 = TopicFactory(forum=self.forum11, author=self.user, is_solved=False, is_sticky=False)
+        PostFactory(topic=topic1, author=self.user, position=1)
+        PostFactory(topic=topic1, author=user1, position=2)
+        PostFactory(topic=topic1, author=self.user, position=3)
+
+        # create a new sticky topic with answers
+        topic2 = TopicFactory(forum=self.forum11, author=self.user, is_solved=False, is_sticky=True)
+        PostFactory(topic=topic2, author=self.user, position=1)
+        PostFactory(topic=topic2, author=user1, position=2)
+        PostFactory(topic=topic2, author=self.user, position=3)
+
+        # all normal (== not sticky) topics
+        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=False)), 3)  # 2 normal + 1 with answers
+        self.assertEqual(get_topics(forum_pk=self.forum11.pk, is_sticky=False)[0], topic1)
+
+        # all sticky topics
+        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=True)), 3)  # 2 normal + 1 with answers
+        self.assertEqual(get_topics(forum_pk=self.forum11.pk, is_sticky=True)[0], topic2)
+
+        # no answer topics
+        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=False, filter='noanswer')), 2)
+        self.assertEqual(get_topics(forum_pk=self.forum11.pk, is_sticky=False, filter='noanswer')[0], topic_solved)
+
+        # no answer sticky topics
+        self.assertEqual(len(get_topics(forum_pk=self.forum11.pk, is_sticky=True, filter='noanswer')), 2)
+        self.assertEqual(
+            get_topics(forum_pk=self.forum11.pk, is_sticky=True, filter='noanswer')[0],
+            topic_solved_sticky
+        )