Browse Source

Add tests for hide/unhide

Alec Nikolas Reiter 7 years ago
parent
commit
047a19693c

+ 47 - 33
flaskbb/forum/models.py

@@ -15,7 +15,7 @@ from sqlalchemy.orm import aliased
 
 from flaskbb.extensions import db
 from flaskbb.utils.database import (CRUDMixin, HideableCRUDMixin, UTCDateTime,
-                                    make_comparable)
+                                    make_comparable, HideableQuery)
 from flaskbb.utils.helpers import (get_categories_and_forums, get_forums,
                                    slugify, time_utcnow, topic_is_unread)
 from flaskbb.utils.settings import flaskbb_config
@@ -212,20 +212,21 @@ class Post(HideableCRUDMixin, db.Model):
             self.topic = topic
             self.date_created = created
 
-            topic.last_updated = created
-            topic.last_post = self
+            if not topic.hidden:
+                topic.last_updated = created
+                topic.last_post = self
 
-            # Update the last post info for the forum
-            topic.forum.last_post = self
-            topic.forum.last_post_user = self.user
-            topic.forum.last_post_title = topic.title
-            topic.forum.last_post_username = user.username
-            topic.forum.last_post_created = created
+                # Update the last post info for the forum
+                topic.forum.last_post = self
+                topic.forum.last_post_user = self.user
+                topic.forum.last_post_title = topic.title
+                topic.forum.last_post_username = user.username
+                topic.forum.last_post_created = created
 
-            # Update the post counts
-            user.post_count += 1
-            topic.post_count += 1
-            topic.forum.post_count += 1
+                # Update the post counts
+                user.post_count += 1
+                topic.post_count += 1
+                topic.forum.post_count += 1
 
             # And commit it!
             db.session.add(topic)
@@ -254,9 +255,9 @@ class Post(HideableCRUDMixin, db.Model):
             self.topic.hide(user)
             return self
 
+        super(Post, self).hide(user)
         self._deal_with_last_post()
         self._update_counts()
-        super(Post, self).hide(user)
         db.session.commit()
         return self
 
@@ -270,6 +271,7 @@ class Post(HideableCRUDMixin, db.Model):
 
         self._restore_post_to_topic()
         super(Post, self).unhide()
+        self._update_counts()
         db.session.commit()
         return self
 
@@ -280,19 +282,28 @@ class Post(HideableCRUDMixin, db.Model):
             if self.topic.last_post == self.topic.forum.last_post:
                 # We need the second last post in the forum here,
                 # because the last post will be deleted
-                second_last_post = Post.query.\
-                    filter(Post.topic_id == Topic.id,
-                           Topic.forum_id == self.topic.forum.id).\
-                    order_by(Post.id.desc()).limit(2).offset(0).\
-                    all()
-
-                # now lets update the second last post to the last post
-                last_post = second_last_post[1]
-                self.topic.forum.last_post = last_post
-                self.topic.forum.last_post_title = last_post.topic.title
-                self.topic.forum.last_post_user = last_post.user
-                self.topic.forum.last_post_username = last_post.username
-                self.topic.forum.last_post_created = last_post.date_created
+                second_last_post = Post.query.filter(
+                    Post.topic_id == Topic.id,
+                    Topic.forum_id == self.topic.forum.id,
+                    Post.hidden != True,
+                    Post.id != self.id
+                ).order_by(
+                    Post.id.desc()
+                ).limit(1).first()
+
+                if second_last_post:
+                    # now lets update the second last post to the last post
+                    self.topic.forum.last_post = second_last_post
+                    self.topic.forum.last_post_title = second_last_post.topic.title
+                    self.topic.forum.last_post_user = second_last_post.user
+                    self.topic.forum.last_post_username = second_last_post.username
+                    self.topic.forum.last_post_created = second_last_post.date_created
+                else:
+                    self.topic.forum.last_post = None
+                    self.topic.forum.last_post_title = None
+                    self.topic.forum.last_post_user = None
+                    self.topic.forum.last_post_username = None
+                    self.topic.forum.last_post_created = None
 
             # check if there is a second last post in this topic
             if self.topic.second_last_post:
@@ -340,7 +351,8 @@ class Post(HideableCRUDMixin, db.Model):
     def _restore_post_to_topic(self):
         last_unhidden_post = Post.query.filter(
             Post.topic_id == self.topic_id,
-            Post.id != self.id
+            Post.id != self.id,
+            Post.hidden != True,
         ).limit(1).first()
 
         # should never be None, but deal with it anyways to be safe
@@ -952,11 +964,13 @@ class Forum(db.Model, CRUDMixin):
         :param last_post: If set to ``True`` it will also try to update
                           the last post columns in the forum.
         """
-        topic_count = Topic.query.filter_by(forum_id=self.id).count()
-        post_count = Post.query.\
-            filter(Post.topic_id == Topic.id,
-                   Topic.forum_id == self.id).\
-            count()
+        topic_count = Topic.query.filter(Forum.id == self.id, Topic.hidden != True).count()
+        post_count = Post.query.filter(
+            Post.topic_id == Topic.id,
+            Topic.forum_id == self.id,
+            Post.hidden != True,
+            Topic.hidden != True
+        ).count()
         self.topic_count = topic_count
         self.post_count = post_count
 

+ 6 - 0
tests/fixtures/app.py

@@ -20,6 +20,12 @@ def application():
     ctx.pop()
 
 
+@pytest.yield_fixture()
+def request_context(application):
+    with application.test_request_context():
+        yield
+
+
 @pytest.fixture()
 def default_groups(database):
     """Creates the default groups"""

+ 63 - 0
tests/unit/test_forum_models.py

@@ -574,3 +574,66 @@ def test_topicsread(topic, user):
         filter_by(topic_id=topicsread.topic_id).\
         first()
     assert topicsread is None
+
+
+def test_hiding_post_updates_counts(forum, topic, user):
+    new_post = Post(content='spam')
+    new_post.save(user=user, topic=topic)
+    new_post.hide(user)
+    assert user.post_count == 1
+    assert topic.post_count == 1
+    assert forum.post_count == 1
+    assert topic.last_post != new_post
+    assert forum.last_post != new_post
+    assert new_post.hidden_by == user
+    new_post.unhide()
+    assert topic.post_count == 2
+    assert user.post_count == 2
+    assert forum.post_count == 2
+    assert topic.last_post == new_post
+    assert forum.last_post == new_post
+    assert new_post.hidden_by is None
+
+
+def test_hiding_topic_updates_counts(forum, topic, user):
+    assert forum.post_count == 1
+    topic.hide(user)
+    assert forum.post_count == 0
+    assert topic.hidden_by == user
+    assert forum.last_post is None
+    topic.unhide()
+    assert forum.post_count == 1
+    assert topic.hidden_by is None
+    assert forum.last_post == topic.last_post
+
+
+def test_hiding_first_post_hides_topic(forum, topic, user):
+    assert forum.post_count == 1
+    topic.first_post.hide(user)
+    assert forum.post_count == 0
+    assert topic.hidden_by == user
+    assert forum.last_post is None
+    topic.first_post.unhide()
+    assert forum.post_count == 1
+    assert topic.hidden_by is None
+    assert forum.last_post == topic.last_post
+
+
+def test_retrieving_hidden_posts(topic, user):
+    new_post = Post(content='stuff')
+    new_post.save(user, topic)
+    new_post.hide(user)
+
+    assert Post.query.get(new_post.id) is None
+    assert Post.query.get(new_post.id, include_hidden=True) == new_post
+    assert Post.query.filter(Post.id == new_post.id).first() is None
+    assert Post.query.with_hidden().filter(Post.id == new_post.id).first() == new_post
+
+
+def test_retrieving_hidden_topics(topic, user):
+    topic.hide(user)
+
+    assert Topic.query.get(topic.id) is None
+    assert Topic.query.get(topic.id, include_hidden=True) == topic
+    assert Topic.query.filter(Topic.id == topic.id).first() is None
+    assert Topic.query.with_hidden().filter(Topic.id == topic.id).first() == topic

+ 32 - 0
tests/unit/test_hideable_query.py

@@ -0,0 +1,32 @@
+from flask_login import login_user
+from flaskbb.forum.models import Topic
+
+
+def test_guest_user_cannot_see_hidden_posts(guest, topic, user, request_context):
+    topic.hide(user)
+    login_user(guest)
+    assert Topic.query.filter(Topic.id == topic.id).first() is None
+
+
+def test_regular_user_cannot_see_hidden_posts(topic, user, request_context):
+    topic.hide(user)
+    login_user(user)
+    assert Topic.query.filter(Topic.id == topic.id).first() is None
+
+
+def test_moderator_user_can_see_hidden_posts(topic, moderator_user, request_context):
+    topic.hide(moderator_user)
+    login_user(moderator_user)
+    assert Topic.query.filter(Topic.id == topic.id).first() is not None
+
+
+def test_super_moderator_user_can_see_hidden_posts(topic, super_moderator_user, request_context):
+    topic.hide(super_moderator_user)
+    login_user(super_moderator_user)
+    assert Topic.query.filter(Topic.id == topic.id).first() is not None
+
+
+def test_admin_user_can_see_hidden_posts(topic, admin_user, request_context):
+    topic.hide(admin_user)
+    login_user(admin_user)
+    assert Topic.query.filter(Topic.id == topic.id).first() is not None

+ 1 - 0
tests/unit/test_posts.py

@@ -0,0 +1 @@
+