rafalp 6 лет назад
Родитель
Сommit
2f0befd230

+ 1 - 1
misago/threads/serializers/moderation.py

@@ -223,7 +223,7 @@ class MovePostsSerializer(serializers.Serializer):
         request = self.context['request']
         thread = self.context['thread']
 
-        posts_queryset = exclude_invisible_posts(request.user, thread.category, thread.post_set)
+        posts_queryset = exclude_invisible_posts(request.user_acl, thread.category, thread.post_set)
         posts_queryset = posts_queryset.filter(id__in=data).order_by('id')
 
         posts = []

+ 50 - 94
misago/threads/tests/test_thread_postmove_api.py

@@ -2,12 +2,12 @@ import json
 
 from django.urls import reverse
 
-from misago.acl.testutils import override_acl
 from misago.categories.models import Category
 from misago.readtracker import poststracker
 from misago.threads import testutils
 from misago.threads.models import Thread
 from misago.threads.serializers.moderation import POSTS_LIMIT
+from misago.threads.test import patch_category_acl, patch_other_category_acl
 from misago.users.testutils import AuthenticatedUserTestCase
 
 
@@ -25,66 +25,14 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
         )
 
         Category(
-            name='Category B',
-            slug='category-b',
+            name='Other category',
+            slug='other-category',
         ).insert_at(
             self.category,
             position='last-child',
             save=True,
         )
-        self.category_b = Category.objects.get(slug='category-b')
-
-        self.override_acl()
-        self.override_other_acl()
-
-    def refresh_thread(self):
-        self.thread = Thread.objects.get(pk=self.thread.pk)
-
-    def override_acl(self, extra_acl=None):
-        new_acl = self.user.acl_cache
-        new_acl['categories'][self.category.pk].update({
-            'can_see': 1,
-            'can_browse': 1,
-            'can_start_threads': 1,
-            'can_reply_threads': 1,
-            'can_edit_posts': 1,
-            'can_approve_content': 0,
-            'can_move_posts': 1,
-        })
-
-        if extra_acl:
-            new_acl['categories'][self.category.pk].update(extra_acl)
-
-        override_acl(self.user, new_acl)
-
-    def override_other_acl(self, extra_acl=None):
-        other_category_acl = self.user.acl_cache['categories'][self.category.pk].copy()
-        other_category_acl.update({
-            'can_see': 1,
-            'can_browse': 1,
-            'can_start_threads': 0,
-            'can_reply_threads': 0,
-            'can_edit_posts': 1,
-            'can_approve_content': 0,
-            'can_move_posts': 1,
-        })
-
-        if extra_acl:
-            other_category_acl.update(extra_acl)
-
-        categories_acl = self.user.acl_cache['categories']
-        categories_acl[self.category_b.pk] = other_category_acl
-
-        visible_categories = [self.category.pk]
-        if other_category_acl['can_see']:
-            visible_categories.append(self.category_b.pk)
-
-        override_acl(
-            self.user, {
-                'visible_categories': visible_categories,
-                'categories': categories_acl,
-            }
-        )
+        self.other_category = Category.objects.get(slug='other-category')
 
     def test_anonymous_user(self):
         """you need to authenticate to move posts"""
@@ -96,46 +44,43 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "This action is not available to guests.",
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_invalid_data(self):
         """api handles post that is invalid type"""
-        self.override_acl()
         response = self.client.post(self.api_link, '[]', content_type="application/json")
         self.assertEqual(response.status_code, 400)
         self.assertEqual(response.json(), {
             "detail": "Invalid data. Expected a dictionary, but got list.",
         })
 
-        self.override_acl()
         response = self.client.post(self.api_link, '123', content_type="application/json")
         self.assertEqual(response.status_code, 400)
         self.assertEqual(response.json(), {
             "detail": "Invalid data. Expected a dictionary, but got int.",
         })
 
-        self.override_acl()
         response = self.client.post(self.api_link, '"string"', content_type="application/json")
         self.assertEqual(response.status_code, 400)
         self.assertEqual(response.json(), {
             "detail": "Invalid data. Expected a dictionary, but got str.",
         })
 
-        self.override_acl()
         response = self.client.post(self.api_link, 'malformed', content_type="application/json")
         self.assertEqual(response.status_code, 400)
         self.assertEqual(response.json(), {
             "detail": "JSON parse error - Expecting value: line 1 column 1 (char 0)",
         })
 
+    @patch_category_acl({"can_move_posts": False})
     def test_no_permission(self):
         """api validates permission to move"""
-        self.override_acl({'can_move_posts': 0})
-
         response = self.client.post(self.api_link, json.dumps({}), content_type="application/json")
         self.assertEqual(response.status_code, 403)
         self.assertEqual(response.json(), {
             "detail": "You can't move posts in this thread.",
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_move_no_new_thread_url(self):
         """api validates if new thread url was given"""
         response = self.client.post(self.api_link)
@@ -144,6 +89,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "Enter link to new thread.",
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_invalid_new_thread_url(self):
         """api validates new thread url"""
         response = self.client.post(self.api_link, {
@@ -154,6 +100,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "This is not a valid thread link.",
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_current_new_thread_url(self):
         """api validates if new thread url points to current thread"""
         response = self.client.post(
@@ -166,16 +113,14 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "Thread to move posts to is same as current one.",
         })
 
+    @patch_other_category_acl({"can_see": False})
+    @patch_category_acl({"can_move_posts": True})
     def test_other_thread_exists(self):
         """api validates if other thread exists"""
-        self.override_other_acl()
-
-        other_thread = testutils.post_thread(self.category_b)
-        other_new_thread = other_thread.get_absolute_url()
-        other_thread.delete()
+        other_thread = testutils.post_thread(self.other_category)
 
         response = self.client.post(self.api_link, {
-            'new_thread': other_new_thread,
+            'new_thread': other_thread.get_absolute_url(),
         })
         self.assertEqual(response.status_code, 400)
         self.assertEqual(response.json(), {
@@ -185,11 +130,11 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             ),
         })
 
+    @patch_other_category_acl({"can_browse": False})
+    @patch_category_acl({"can_move_posts": True})
     def test_other_thread_is_invisible(self):
         """api validates if other thread is visible"""
-        self.override_other_acl({'can_see': 0})
-
-        other_thread = testutils.post_thread(self.category_b)
+        other_thread = testutils.post_thread(self.other_category)
 
         response = self.client.post(
             self.api_link, {
@@ -204,11 +149,11 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             ),
         })
 
+    @patch_other_category_acl({"can_reply_threads": False})
+    @patch_category_acl({"can_move_posts": True})
     def test_other_thread_isnt_replyable(self):
         """api validates if other thread can be replied"""
-        self.override_other_acl({'can_reply_threads': 0})
-
-        other_thread = testutils.post_thread(self.category_b)
+        other_thread = testutils.post_thread(self.other_category)
 
         response = self.client.post(
             self.api_link, {
@@ -220,6 +165,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "You can't move posts to threads you can't reply.",
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_empty_data(self):
         """api handles empty data"""
         other_thread = testutils.post_thread(self.category)
@@ -230,6 +176,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "Enter link to new thread.",
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_empty_posts_data_json(self):
         """api handles empty json data"""
         other_thread = testutils.post_thread(self.category)
@@ -246,6 +193,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "You have to specify at least one post to move.",
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_empty_posts_data_form(self):
         """api handles empty form data"""
         other_thread = testutils.post_thread(self.category)
@@ -261,6 +209,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "You have to specify at least one post to move.",
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_no_posts_ids(self):
         """api rejects no posts ids"""
         other_thread = testutils.post_thread(self.category)
@@ -278,6 +227,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "You have to specify at least one post to move.",
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_invalid_posts_data(self):
         """api handles invalid data"""
         other_thread = testutils.post_thread(self.category)
@@ -295,6 +245,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": 'Expected a list of items but got type "str".',
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_invalid_posts_ids(self):
         """api handles invalid post id"""
         other_thread = testutils.post_thread(self.category)
@@ -312,6 +263,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "One or more post ids received were invalid.",
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_move_limit(self):
         """api rejects more posts than move limit"""
         other_thread = testutils.post_thread(self.category)
@@ -329,6 +281,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "No more than %s posts can be moved at single time." % POSTS_LIMIT,
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_move_invisible(self):
         """api validates posts visibility"""
         other_thread = testutils.post_thread(self.category)
@@ -346,6 +299,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "One or more posts to move could not be found.",
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_move_other_thread_posts(self):
         """api recjects attempt to move other thread's post"""
         other_thread = testutils.post_thread(self.category)
@@ -363,6 +317,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "One or more posts to move could not be found.",
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_move_event(self):
         """api rejects events move"""
         other_thread = testutils.post_thread(self.category)
@@ -380,6 +335,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "Events can't be moved.",
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_move_first_post(self):
         """api rejects first post move"""
         other_thread = testutils.post_thread(self.category)
@@ -397,6 +353,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "You can't move thread's first post.",
         })
 
+    @patch_category_acl({"can_move_posts": True})
     def test_move_hidden_posts(self):
         """api recjects attempt to move urneadable hidden post"""
         other_thread = testutils.post_thread(self.category)
@@ -414,6 +371,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "You can't move posts the content you can't see.",
         })
 
+    @patch_category_acl({"can_move_posts": True, "can_close_threads": False})
     def test_move_posts_closed_thread_no_permission(self):
         """api recjects attempt to move posts from closed thread"""
         other_thread = testutils.post_thread(self.category)
@@ -421,8 +379,6 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
         self.thread.is_closed = True
         self.thread.save()
 
-        self.override_acl({'can_close_threads': 0})
-
         response = self.client.post(
             self.api_link,
             json.dumps({
@@ -436,16 +392,15 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "This thread is closed. You can't move posts in it.",
         })
 
+    @patch_other_category_acl({"can_reply_threads": True, "can_close_threads": False})
+    @patch_category_acl({"can_move_posts": True})
     def test_move_posts_closed_category_no_permission(self):
         """api recjects attempt to move posts from closed thread"""
-        other_thread = testutils.post_thread(self.category_b)
+        other_thread = testutils.post_thread(self.other_category)
 
         self.category.is_closed = True
         self.category.save()
 
-        self.override_acl({'can_close_threads': 0})
-        self.override_other_acl({'can_reply_threads': 1})
-
         response = self.client.post(
             self.api_link,
             json.dumps({
@@ -459,11 +414,11 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             "detail": "This category is closed. You can't move posts in it.",
         })
 
+    @patch_other_category_acl({"can_reply_threads": True})
+    @patch_category_acl({"can_move_posts": True})
     def test_move_posts(self):
         """api moves posts to other thread"""
-        self.override_other_acl({'can_reply_threads': 1})
-
-        other_thread = testutils.post_thread(self.category_b)
+        other_thread = testutils.post_thread(self.other_category)
 
         posts = (
             testutils.reply_thread(self.thread).pk,
@@ -472,7 +427,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
             testutils.reply_thread(self.thread).pk,
         )
 
-        self.refresh_thread()
+        self.thread.refresh_from_db()
         self.assertEqual(self.thread.replies, 4)
 
         response = self.client.post(
@@ -486,25 +441,25 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
         self.assertEqual(response.status_code, 200)
 
         # replies were moved
-        self.refresh_thread()
+        self.thread.refresh_from_db()
         self.assertEqual(self.thread.replies, 0)
 
         other_thread = Thread.objects.get(pk=other_thread.pk)
         self.assertEqual(other_thread.post_set.filter(pk__in=posts).count(), 4)
         self.assertEqual(other_thread.replies, 4)
 
+    @patch_other_category_acl({"can_reply_threads": True})
+    @patch_category_acl({"can_move_posts": True})
     def test_move_best_answer(self):
         """api moves best answer to other thread"""
-        self.override_other_acl({'can_reply_threads': 1})
-
-        other_thread = testutils.post_thread(self.category_b)
+        other_thread = testutils.post_thread(self.other_category)
         best_answer = testutils.reply_thread(self.thread)
 
         self.thread.set_best_answer(self.user, best_answer)
         self.thread.synchronize()
         self.thread.save()
 
-        self.refresh_thread()
+        self.thread.refresh_from_db()
         self.assertEqual(self.thread.best_answer, best_answer)
         self.assertEqual(self.thread.replies, 1)
 
@@ -519,7 +474,7 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
         self.assertEqual(response.status_code, 200)
 
         # best_answer was moved and unmarked
-        self.refresh_thread()
+        self.thread.refresh_from_db()
         self.assertEqual(self.thread.replies, 0)
         self.assertIsNone(self.thread.best_answer)
 
@@ -527,18 +482,19 @@ class ThreadPostMoveApiTestCase(AuthenticatedUserTestCase):
         self.assertEqual(other_thread.replies, 1)
         self.assertIsNone(other_thread.best_answer)
 
+
+    @patch_other_category_acl({"can_reply_threads": True})
+    @patch_category_acl({"can_move_posts": True})
     def test_move_posts_reads(self):
         """api moves posts reads together with posts"""
-        self.override_other_acl({'can_reply_threads': 1})
-
-        other_thread = testutils.post_thread(self.category_b)
+        other_thread = testutils.post_thread(self.other_category)
 
         posts = (
             testutils.reply_thread(self.thread),
             testutils.reply_thread(self.thread),
         )
 
-        self.refresh_thread()
+        self.thread.refresh_from_db()
         self.assertEqual(self.thread.replies, 2)
 
         poststracker.save_read(self.user, self.thread.first_post)