Browse Source

Fix tests for threads editor api

rafalp 6 years ago
parent
commit
4307c0acb9

+ 1 - 1
misago/threads/api/threadendpoints/editor.py

@@ -27,7 +27,7 @@ def thread_start_editor(request):
         add_acl(request.user_acl, category)
         add_acl(request.user_acl, category)
 
 
         post = False
         post = False
-        if can_start_thread(request.user, category):
+        if can_start_thread(request.user_acl, category):
             post = {
             post = {
                 'close': bool(category.acl['can_close_threads']),
                 'close': bool(category.acl['can_close_threads']),
                 'hide': bool(category.acl['can_hide_threads']),
                 'hide': bool(category.acl['can_hide_threads']),

+ 5 - 5
misago/threads/api/threadposts.py

@@ -86,7 +86,7 @@ class ViewSet(viewsets.ViewSet):
     @transaction.atomic
     @transaction.atomic
     def create(self, request, thread_pk):
     def create(self, request, thread_pk):
         thread = self.get_thread(request, thread_pk).unwrap()
         thread = self.get_thread(request, thread_pk).unwrap()
-        allow_reply_thread(request.user, thread)
+        allow_reply_thread(request.user_acl, thread)
 
 
         post = Post(
         post = Post(
             thread=thread,
             thread=thread,
@@ -122,7 +122,7 @@ class ViewSet(viewsets.ViewSet):
         thread = self.get_thread(request, thread_pk).unwrap()
         thread = self.get_thread(request, thread_pk).unwrap()
         post = self.get_post(request, thread, pk).unwrap()
         post = self.get_post(request, thread, pk).unwrap()
 
 
-        allow_edit_post(request.user, post)
+        allow_edit_post(request.user_acl, post)
 
 
         posting = PostingEndpoint(
         posting = PostingEndpoint(
             request,
             request,
@@ -188,7 +188,7 @@ class ViewSet(viewsets.ViewSet):
         thread = self.get_thread(request, thread_pk)
         thread = self.get_thread(request, thread_pk)
         post = self.get_post(request, thread, pk).unwrap()
         post = self.get_post(request, thread, pk).unwrap()
 
 
-        allow_edit_post(request.user, post)
+        allow_edit_post(request.user_acl, post)
 
 
         attachments = []
         attachments = []
         for attachment in post.attachment_set.order_by('-id'):
         for attachment in post.attachment_set.order_by('-id'):
@@ -211,7 +211,7 @@ class ViewSet(viewsets.ViewSet):
     @list_route(methods=['get'], url_path='editor')
     @list_route(methods=['get'], url_path='editor')
     def reply_editor(self, request, thread_pk):
     def reply_editor(self, request, thread_pk):
         thread = self.get_thread(request, thread_pk).unwrap()
         thread = self.get_thread(request, thread_pk).unwrap()
-        allow_reply_thread(request.user, thread)
+        allow_reply_thread(request.user_acl, thread)
 
 
         if 'reply' in request.query_params:
         if 'reply' in request.query_params:
             reply_to = self.get_post(request, thread, request.query_params['reply']).unwrap()
             reply_to = self.get_post(request, thread, request.query_params['reply']).unwrap()
@@ -242,7 +242,7 @@ class ViewSet(viewsets.ViewSet):
                 thread = self.get_thread(request, thread_pk)
                 thread = self.get_thread(request, thread_pk)
                 post = self.get_post(request, thread, pk).unwrap()
                 post = self.get_post(request, thread, pk).unwrap()
 
 
-                allow_edit_post(request.user, post)
+                allow_edit_post(request.user_acl, post)
 
 
                 return revert_post_endpoint(request, post)
                 return revert_post_endpoint(request, post)
 
 

+ 137 - 221
misago/threads/tests/test_threads_editor_api.py

@@ -2,18 +2,19 @@ import os
 
 
 from django.urls import reverse
 from django.urls import reverse
 
 
-from misago.acl import add_acl
-from misago.acl.testutils import override_acl
+from misago.acl import add_acl, useracl
 from misago.categories.models import Category
 from misago.categories.models import Category
 from misago.threads import testutils
 from misago.threads import testutils
 from misago.threads.models import Attachment
 from misago.threads.models import Attachment
 from misago.threads.serializers import AttachmentSerializer
 from misago.threads.serializers import AttachmentSerializer
+from misago.threads.test import patch_category_acl
 from misago.users.testutils import AuthenticatedUserTestCase
 from misago.users.testutils import AuthenticatedUserTestCase
 
 
-
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'testfiles')
 TESTFILES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'testfiles')
 TEST_DOCUMENT_PATH = os.path.join(TESTFILES_DIR, 'document.pdf')
 TEST_DOCUMENT_PATH = os.path.join(TESTFILES_DIR, 'document.pdf')
 
 
+cache_versions = {"acl": "abcdefgh"}
+
 
 
 class EditorApiTestCase(AuthenticatedUserTestCase):
 class EditorApiTestCase(AuthenticatedUserTestCase):
     def setUp(self):
     def setUp(self):
@@ -21,53 +22,6 @@ class EditorApiTestCase(AuthenticatedUserTestCase):
 
 
         self.category = Category.objects.get(slug='first-category')
         self.category = Category.objects.get(slug='first-category')
 
 
-    def override_acl(self, acl=None):
-        final_acl = self.user.acl_cache['categories'][self.category.pk]
-        final_acl.update({
-            'can_see': 1,
-            'can_browse': 1,
-            'can_see_all_threads': 1,
-            'can_start_threads': 0,
-            'can_reply_threads': 0,
-            'can_edit_threads': 0,
-            'can_edit_posts': 0,
-            'can_hide_own_threads': 0,
-            'can_hide_own_posts': 0,
-            'thread_edit_time': 0,
-            'post_edit_time': 0,
-            'can_hide_threads': 0,
-            'can_hide_posts': 0,
-            'can_protect_posts': 0,
-            'can_move_posts': 0,
-            'can_merge_posts': 0,
-            'can_pin_threads': 0,
-            'can_close_threads': 0,
-            'can_move_threads': 0,
-            'can_merge_threads': 0,
-            'can_approve_content': 0,
-            'can_report_content': 0,
-            'can_see_reports': 0,
-            'can_see_posts_likes': 0,
-            'can_like_posts': 0,
-            'can_hide_events': 0,
-        })
-
-        if acl:
-            final_acl.update(acl)
-
-        browseable_categories = []
-        if final_acl['can_browse']:
-            browseable_categories.append(self.category.pk)
-
-        override_acl(
-            self.user, {
-                'browseable_categories': browseable_categories,
-                'categories': {
-                    self.category.pk: final_acl,
-                },
-            }
-        )
-
 
 
 class ThreadPostEditorApiTests(EditorApiTestCase):
 class ThreadPostEditorApiTests(EditorApiTestCase):
     def setUp(self):
     def setUp(self):
@@ -85,30 +39,27 @@ class ThreadPostEditorApiTests(EditorApiTestCase):
             "detail": "You need to be signed in to start threads.",
             "detail": "You need to be signed in to start threads.",
         })
         })
 
 
+    @patch_category_acl({'can_browse': False})
     def test_category_visibility_validation(self):
     def test_category_visibility_validation(self):
         """endpoint omits non-browseable categories"""
         """endpoint omits non-browseable categories"""
-        self.override_acl({'can_browse': 0})
-
         response = self.client.get(self.api_link)
         response = self.client.get(self.api_link)
         self.assertEqual(response.status_code, 403)
         self.assertEqual(response.status_code, 403)
         self.assertEqual(response.json(), {
         self.assertEqual(response.json(), {
             "detail": "No categories that allow new threads are available to you at the moment.",
             "detail": "No categories that allow new threads are available to you at the moment.",
         })
         })
 
 
+    @patch_category_acl({'can_start_threads': False})
     def test_category_disallowing_new_threads(self):
     def test_category_disallowing_new_threads(self):
         """endpoint omits category disallowing starting threads"""
         """endpoint omits category disallowing starting threads"""
-        self.override_acl({'can_start_threads': 0})
-
         response = self.client.get(self.api_link)
         response = self.client.get(self.api_link)
         self.assertEqual(response.status_code, 403)
         self.assertEqual(response.status_code, 403)
         self.assertEqual(response.json(), {
         self.assertEqual(response.json(), {
             "detail": "No categories that allow new threads are available to you at the moment.",
             "detail": "No categories that allow new threads are available to you at the moment.",
         })
         })
 
 
+    @patch_category_acl({'can_close_threads': False, 'can_start_threads': True})
     def test_category_closed_disallowing_new_threads(self):
     def test_category_closed_disallowing_new_threads(self):
         """endpoint omits closed category"""
         """endpoint omits closed category"""
-        self.override_acl({'can_start_threads': 2, 'can_close_threads': 0})
-
         self.category.is_closed = True
         self.category.is_closed = True
         self.category.save()
         self.category.save()
 
 
@@ -118,10 +69,9 @@ class ThreadPostEditorApiTests(EditorApiTestCase):
             "detail": "No categories that allow new threads are available to you at the moment.",
             "detail": "No categories that allow new threads are available to you at the moment.",
         })
         })
 
 
+    @patch_category_acl({'can_close_threads': True, 'can_start_threads': True})
     def test_category_closed_allowing_new_threads(self):
     def test_category_closed_allowing_new_threads(self):
         """endpoint adds closed category that allows new threads"""
         """endpoint adds closed category that allows new threads"""
-        self.override_acl({'can_start_threads': 2, 'can_close_threads': 1})
-
         self.category.is_closed = True
         self.category.is_closed = True
         self.category.save()
         self.category.save()
 
 
@@ -142,10 +92,9 @@ class ThreadPostEditorApiTests(EditorApiTestCase):
             }
             }
         )
         )
 
 
+    @patch_category_acl({'can_start_threads': True})
     def test_category_allowing_new_threads(self):
     def test_category_allowing_new_threads(self):
         """endpoint adds category that allows new threads"""
         """endpoint adds category that allows new threads"""
-        self.override_acl({'can_start_threads': 2})
-
         response = self.client.get(self.api_link)
         response = self.client.get(self.api_link)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
@@ -163,10 +112,9 @@ class ThreadPostEditorApiTests(EditorApiTestCase):
             }
             }
         )
         )
 
 
+    @patch_category_acl({'can_close_threads': True, 'can_start_threads': True})
     def test_category_allowing_closing_threads(self):
     def test_category_allowing_closing_threads(self):
         """endpoint adds category that allows new closed threads"""
         """endpoint adds category that allows new closed threads"""
-        self.override_acl({'can_start_threads': 2, 'can_close_threads': 1})
-
         response = self.client.get(self.api_link)
         response = self.client.get(self.api_link)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
@@ -184,10 +132,9 @@ class ThreadPostEditorApiTests(EditorApiTestCase):
             }
             }
         )
         )
 
 
+    @patch_category_acl({'can_start_threads': True, 'can_pin_threads': 1})
     def test_category_allowing_locally_pinned_threads(self):
     def test_category_allowing_locally_pinned_threads(self):
         """endpoint adds category that allows locally pinned threads"""
         """endpoint adds category that allows locally pinned threads"""
-        self.override_acl({'can_start_threads': 2, 'can_pin_threads': 1})
-
         response = self.client.get(self.api_link)
         response = self.client.get(self.api_link)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
@@ -205,10 +152,9 @@ class ThreadPostEditorApiTests(EditorApiTestCase):
             }
             }
         )
         )
 
 
+    @patch_category_acl({'can_start_threads': True, 'can_pin_threads': 2})
     def test_category_allowing_globally_pinned_threads(self):
     def test_category_allowing_globally_pinned_threads(self):
         """endpoint adds category that allows globally pinned threads"""
         """endpoint adds category that allows globally pinned threads"""
-        self.override_acl({'can_start_threads': 2, 'can_pin_threads': 2})
-
         response = self.client.get(self.api_link)
         response = self.client.get(self.api_link)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
@@ -226,10 +172,9 @@ class ThreadPostEditorApiTests(EditorApiTestCase):
             }
             }
         )
         )
 
 
-    def test_category_allowing_hidden_threads(self):
-        """endpoint adds category that allows globally pinned threads"""
-        self.override_acl({'can_start_threads': 2, 'can_hide_threads': 1})
-
+    @patch_category_acl({'can_start_threads': True, 'can_hide_threads': 1})
+    def test_category_allowing_hidding_threads(self):
+        """endpoint adds category that allows hiding threads"""
         response = self.client.get(self.api_link)
         response = self.client.get(self.api_link)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
@@ -247,8 +192,9 @@ class ThreadPostEditorApiTests(EditorApiTestCase):
             }
             }
         )
         )
 
 
-        self.override_acl({'can_start_threads': 2, 'can_hide_threads': 2})
-
+    @patch_category_acl({'can_start_threads': True, 'can_hide_threads': 2})
+    def test_category_allowing_hidding_and_deleting_threads(self):
+        """endpoint adds category that allows hiding and deleting threads"""
         response = self.client.get(self.api_link)
         response = self.client.get(self.api_link)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
@@ -260,7 +206,7 @@ class ThreadPostEditorApiTests(EditorApiTestCase):
                 'level': 0,
                 'level': 0,
                 'post': {
                 'post': {
                     'close': False,
                     'close': False,
-                    'hide': True,
+                    'hide': 1,
                     'pin': 0,
                     'pin': 0,
                 },
                 },
             }
             }
@@ -290,22 +236,21 @@ class ThreadReplyEditorApiTests(EditorApiTestCase):
 
 
     def test_thread_visibility(self):
     def test_thread_visibility(self):
         """thread's visibility is validated"""
         """thread's visibility is validated"""
-        self.override_acl({'can_see': 0})
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 404)
+        with patch_category_acl({'can_see': False}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 404)
 
 
-        self.override_acl({'can_browse': 0})
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 404)
+        with patch_category_acl({'can_browse': False}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 404)
 
 
-        self.override_acl({'can_see_all_threads': 0})
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 404)
+        with patch_category_acl({'can_see_all_threads': False}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 404)
 
 
+    @patch_category_acl({'can_reply_threads': False})
     def test_no_reply_permission(self):
     def test_no_reply_permission(self):
         """permssion to reply is validated"""
         """permssion to reply is validated"""
-        self.override_acl({'can_reply_threads': 0})
-
         response = self.client.get(self.api_link)
         response = self.client.get(self.api_link)
         self.assertEqual(response.status_code, 403)
         self.assertEqual(response.status_code, 403)
         self.assertEqual(response.json(), {
         self.assertEqual(response.json(), {
@@ -314,72 +259,63 @@ class ThreadReplyEditorApiTests(EditorApiTestCase):
 
 
     def test_closed_category(self):
     def test_closed_category(self):
         """permssion to reply in closed category is validated"""
         """permssion to reply in closed category is validated"""
-        self.override_acl({'can_reply_threads': 1, 'can_close_threads': 0})
-
         self.category.is_closed = True
         self.category.is_closed = True
         self.category.save()
         self.category.save()
 
 
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 403)
-        self.assertEqual(response.json(), {
-            "detail": "This category is closed. You can't reply to threads in it.",
-        })
+        with patch_category_acl({'can_reply_threads': True, 'can_close_threads': False}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 403)
+            self.assertEqual(response.json(), {
+                "detail": "This category is closed. You can't reply to threads in it.",
+            })
 
 
         # allow to post in closed category
         # allow to post in closed category
-        self.override_acl({'can_reply_threads': 1, 'can_close_threads': 1})
-
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 200)
+        with patch_category_acl({'can_reply_threads': True, 'can_close_threads': True}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 200)
 
 
     def test_closed_thread(self):
     def test_closed_thread(self):
         """permssion to reply in closed thread is validated"""
         """permssion to reply in closed thread is validated"""
-        self.override_acl({'can_reply_threads': 1, 'can_close_threads': 0})
-
         self.thread.is_closed = True
         self.thread.is_closed = True
         self.thread.save()
         self.thread.save()
 
 
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 403)
-        self.assertEqual(response.json(), {
-            "detail": "You can't reply to closed threads in this category.",
-        })
+        with patch_category_acl({'can_reply_threads': True, 'can_close_threads': False}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 403)
+            self.assertEqual(response.json(), {
+                "detail": "You can't reply to closed threads in this category.",
+            })
 
 
         # allow to post in closed thread
         # allow to post in closed thread
-        self.override_acl({'can_reply_threads': 1, 'can_close_threads': 1})
-
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 200)
+        with patch_category_acl({'can_reply_threads': True, 'can_close_threads': True}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 200)
 
 
+    @patch_category_acl({'can_reply_threads': True})
     def test_allow_reply_thread(self):
     def test_allow_reply_thread(self):
         """api returns 200 code if thread reply is allowed"""
         """api returns 200 code if thread reply is allowed"""
-        self.override_acl({'can_reply_threads': 1})
-
         response = self.client.get(self.api_link)
         response = self.client.get(self.api_link)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
     def test_reply_to_visibility(self):
     def test_reply_to_visibility(self):
         """api validates replied post visibility"""
         """api validates replied post visibility"""
-        self.override_acl({'can_reply_threads': 1})
 
 
         # unapproved reply can't be replied to
         # unapproved reply can't be replied to
-        unapproved_reply = testutils.reply_thread(
-            self.thread,
-            is_unapproved=True,
-        )
+        unapproved_reply = testutils.reply_thread(self.thread, is_unapproved=True)
 
 
-        response = self.client.get('%s?reply=%s' % (self.api_link, unapproved_reply.pk))
-        self.assertEqual(response.status_code, 404)
+        with patch_category_acl({'can_reply_threads': True}):
+            response = self.client.get('%s?reply=%s' % (self.api_link, unapproved_reply.pk))
+            self.assertEqual(response.status_code, 404)
 
 
         # hidden reply can't be replied to
         # hidden reply can't be replied to
-        self.override_acl({'can_reply_threads': 1})
-
         hidden_reply = testutils.reply_thread(self.thread, is_hidden=True)
         hidden_reply = testutils.reply_thread(self.thread, is_hidden=True)
 
 
-        response = self.client.get('%s?reply=%s' % (self.api_link, hidden_reply.pk))
-        self.assertEqual(response.status_code, 403)
-        self.assertEqual(response.json(), {
-            "detail": "You can't reply to hidden posts.",
-        })
+        with patch_category_acl({'can_reply_threads': True}):
+            response = self.client.get('%s?reply=%s' % (self.api_link, hidden_reply.pk))
+            self.assertEqual(response.status_code, 403)
+            self.assertEqual(response.json(), {
+                "detail": "You can't reply to hidden posts.",
+            })
 
 
     def test_reply_to_other_thread_post(self):
     def test_reply_to_other_thread_post(self):
         """api validates is replied post belongs to same thread"""
         """api validates is replied post belongs to same thread"""
@@ -389,10 +325,9 @@ class ThreadReplyEditorApiTests(EditorApiTestCase):
         response = self.client.get('%s?reply=%s' % (self.api_link, reply_to.pk))
         response = self.client.get('%s?reply=%s' % (self.api_link, reply_to.pk))
         self.assertEqual(response.status_code, 404)
         self.assertEqual(response.status_code, 404)
 
 
+    @patch_category_acl({'can_reply_threads': True})
     def test_reply_to_event(self):
     def test_reply_to_event(self):
-        """events can't be edited"""
-        self.override_acl({'can_reply_threads': 1})
-
+        """events can't be replied to"""
         reply_to = testutils.reply_thread(self.thread, is_event=True)
         reply_to = testutils.reply_thread(self.thread, is_event=True)
 
 
         response = self.client.get('%s?reply=%s' % (self.api_link, reply_to.pk))
         response = self.client.get('%s?reply=%s' % (self.api_link, reply_to.pk))
@@ -401,10 +336,9 @@ class ThreadReplyEditorApiTests(EditorApiTestCase):
             "detail": "You can't reply to events.",
             "detail": "You can't reply to events.",
         })
         })
 
 
+    @patch_category_acl({'can_reply_threads': True})
     def test_reply_to(self):
     def test_reply_to(self):
         """api includes replied to post details in response"""
         """api includes replied to post details in response"""
-        self.override_acl({'can_reply_threads': 1})
-
         reply_to = testutils.reply_thread(self.thread)
         reply_to = testutils.reply_thread(self.thread)
 
 
         response = self.client.get('%s?reply=%s' % (self.api_link, reply_to.pk))
         response = self.client.get('%s?reply=%s' % (self.api_link, reply_to.pk))
@@ -446,22 +380,21 @@ class EditReplyEditorApiTests(EditorApiTestCase):
 
 
     def test_thread_visibility(self):
     def test_thread_visibility(self):
         """thread's visibility is validated"""
         """thread's visibility is validated"""
-        self.override_acl({'can_see': 0})
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 404)
+        with patch_category_acl({'can_see': False}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 404)
 
 
-        self.override_acl({'can_browse': 0})
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 404)
+        with patch_category_acl({'can_browse': False}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 404)
 
 
-        self.override_acl({'can_see_all_threads': 0})
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 404)
+        with patch_category_acl({'can_see_all_threads': False}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 404)
 
 
+    @patch_category_acl({'can_edit_posts': 0})
     def test_no_edit_permission(self):
     def test_no_edit_permission(self):
         """permssion to edit is validated"""
         """permssion to edit is validated"""
-        self.override_acl({'can_edit_posts': 0})
-
         response = self.client.get(self.api_link)
         response = self.client.get(self.api_link)
         self.assertEqual(response.status_code, 403)
         self.assertEqual(response.status_code, 403)
         self.assertEqual(response.json(), {
         self.assertEqual(response.json(), {
@@ -470,103 +403,90 @@ class EditReplyEditorApiTests(EditorApiTestCase):
 
 
     def test_closed_category(self):
     def test_closed_category(self):
         """permssion to edit in closed category is validated"""
         """permssion to edit in closed category is validated"""
-        self.override_acl({'can_edit_posts': 1, 'can_close_threads': 0})
-
         self.category.is_closed = True
         self.category.is_closed = True
         self.category.save()
         self.category.save()
 
 
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 403)
-        self.assertEqual(response.json(), {
-            "detail": "This category is closed. You can't edit posts in it.",
-        })
+        with patch_category_acl({'can_edit_posts': 1, 'can_close_threads': False}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 403)
+            self.assertEqual(response.json(), {
+                "detail": "This category is closed. You can't edit posts in it.",
+            })
 
 
         # allow to edit in closed category
         # allow to edit in closed category
-        self.override_acl({'can_edit_posts': 1, 'can_close_threads': 1})
-
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 200)
+        with patch_category_acl({'can_edit_posts': 1, 'can_close_threads': True}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 200)
 
 
     def test_closed_thread(self):
     def test_closed_thread(self):
         """permssion to edit in closed thread is validated"""
         """permssion to edit in closed thread is validated"""
-        self.override_acl({'can_edit_posts': 1, 'can_close_threads': 0})
-
         self.thread.is_closed = True
         self.thread.is_closed = True
         self.thread.save()
         self.thread.save()
 
 
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 403)
-        self.assertEqual(response.json(), {
-            "detail": "This thread is closed. You can't edit posts in it.",
-        })
+        with patch_category_acl({'can_edit_posts': 1, 'can_close_threads': False}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 403)
+            self.assertEqual(response.json(), {
+                "detail": "This thread is closed. You can't edit posts in it.",
+            })
 
 
         # allow to edit in closed thread
         # allow to edit in closed thread
-        self.override_acl({'can_edit_posts': 1, 'can_close_threads': 1})
-
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 200)
+        with patch_category_acl({'can_edit_posts': 1, 'can_close_threads': True}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 200)
 
 
     def test_protected_post(self):
     def test_protected_post(self):
         """permssion to edit protected post is validated"""
         """permssion to edit protected post is validated"""
-        self.override_acl({'can_edit_posts': 1, 'can_protect_posts': 0})
-
         self.post.is_protected = True
         self.post.is_protected = True
         self.post.save()
         self.post.save()
 
 
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 403)
-        self.assertEqual(response.json(), {
-            "detail": "This post is protected. You can't edit it.",
-        })
+        with patch_category_acl({'can_edit_posts': 1, 'can_protect_posts': False}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 403)
+            self.assertEqual(response.json(), {
+                "detail": "This post is protected. You can't edit it.",
+            })
 
 
         # allow to post in closed thread
         # allow to post in closed thread
-        self.override_acl({'can_edit_posts': 1, 'can_protect_posts': 1})
-
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 200)
+        with patch_category_acl({'can_edit_posts': 1, 'can_protect_posts': True}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 200)
 
 
     def test_post_visibility(self):
     def test_post_visibility(self):
         """edited posts visibility is validated"""
         """edited posts visibility is validated"""
-        self.override_acl({'can_edit_posts': 1})
-
         self.post.is_hidden = True
         self.post.is_hidden = True
         self.post.save()
         self.post.save()
 
 
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 403)
-        self.assertEqual(response.json(), {
-            "detail": "This post is hidden, you can't edit it.",
-        })
+        with patch_category_acl({'can_edit_posts': 1}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 403)
+            self.assertEqual(response.json(), {
+                "detail": "This post is hidden, you can't edit it.",
+            })
 
 
         # allow hidden edition
         # allow hidden edition
-        self.override_acl({'can_edit_posts': 1, 'can_hide_posts': 1})
-
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 200)
+        with patch_category_acl({'can_edit_posts': 1, 'can_hide_posts': 1}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 200)
 
 
         # test unapproved post
         # test unapproved post
+        self.post.is_unapproved = True
         self.post.is_hidden = False
         self.post.is_hidden = False
         self.post.poster = None
         self.post.poster = None
         self.post.save()
         self.post.save()
 
 
-        self.override_acl({'can_edit_posts': 2, 'can_approve_content': 0})
-
-        self.post.is_unapproved = True
-        self.post.save()
-
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 404)
+        with patch_category_acl({'can_edit_posts': 2, 'can_approve_content': 0}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 404)
 
 
         # allow unapproved edition
         # allow unapproved edition
-        self.override_acl({'can_edit_posts': 2, 'can_approve_content': 1})
-
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 200)
+        with patch_category_acl({'can_edit_posts': 2, 'can_approve_content': 1}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 200)
 
 
+    @patch_category_acl({'can_edit_posts': 2})
     def test_post_is_event(self):
     def test_post_is_event(self):
         """events can't be edited"""
         """events can't be edited"""
-        self.override_acl()
-
         self.post.is_event = True
         self.post.is_event = True
         self.post.save()
         self.post.save()
 
 
@@ -578,27 +498,24 @@ class EditReplyEditorApiTests(EditorApiTestCase):
 
 
     def test_other_user_post(self):
     def test_other_user_post(self):
         """api validates if other user's post can be edited"""
         """api validates if other user's post can be edited"""
-        self.override_acl({'can_edit_posts': 1})
-
         self.post.poster = None
         self.post.poster = None
         self.post.save()
         self.post.save()
 
 
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 403)
-        self.assertEqual(response.json(), {
-            "detail": "You can't edit other users posts in this category.",
-        })
+        with patch_category_acl({'can_edit_posts': 1}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 403)
+            self.assertEqual(response.json(), {
+                "detail": "You can't edit other users posts in this category.",
+            })
 
 
         # allow other users post edition
         # allow other users post edition
-        self.override_acl({'can_edit_posts': 2})
-
-        response = self.client.get(self.api_link)
-        self.assertEqual(response.status_code, 200)
+        with patch_category_acl({'can_edit_posts': 2}):
+            response = self.client.get(self.api_link)
+            self.assertEqual(response.status_code, 200)
 
 
+    @patch_category_acl({'can_hide_threads': 1, 'can_edit_posts': 2})
     def test_edit_first_post_hidden(self):
     def test_edit_first_post_hidden(self):
         """endpoint returns valid configuration for editor of hidden thread's first post"""
         """endpoint returns valid configuration for editor of hidden thread's first post"""
-        self.override_acl({'can_hide_threads': 1, 'can_edit_posts': 2})
-
         self.thread.is_hidden = True
         self.thread.is_hidden = True
         self.thread.save()
         self.thread.save()
         self.thread.first_post.is_hidden = True
         self.thread.first_post.is_hidden = True
@@ -615,18 +532,18 @@ class EditReplyEditorApiTests(EditorApiTestCase):
         response = self.client.get(api_link)
         response = self.client.get(api_link)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
+    @patch_category_acl({'can_edit_posts': 1})
     def test_edit(self):
     def test_edit(self):
         """endpoint returns valid configuration for editor"""
         """endpoint returns valid configuration for editor"""
-        for _ in range(3):
-            self.override_acl({'max_attachment_size': 1000})
-
-            with open(TEST_DOCUMENT_PATH, 'rb') as upload:
-                response = self.client.post(
-                    reverse('misago:api:attachment-list'), data={
-                        'upload': upload,
-                    }
-                )
-            self.assertEqual(response.status_code, 200)
+        with patch_category_acl({'max_attachment_size': 1000}):
+            for _ in range(3):
+                with open(TEST_DOCUMENT_PATH, 'rb') as upload:
+                    response = self.client.post(
+                        reverse('misago:api:attachment-list'), data={
+                            'upload': upload,
+                        }
+                    )
+                self.assertEqual(response.status_code, 200)
 
 
         attachments = list(Attachment.objects.order_by('id'))
         attachments = list(Attachment.objects.order_by('id'))
 
 
@@ -637,11 +554,10 @@ class EditReplyEditorApiTests(EditorApiTestCase):
             attachment.post = self.post
             attachment.post = self.post
             attachment.save()
             attachment.save()
 
 
-        self.override_acl({'can_edit_posts': 1})
         response = self.client.get(self.api_link)
         response = self.client.get(self.api_link)
-
+        user_acl = useracl.get_user_acl(self.user, cache_versions)
         for attachment in attachments:
         for attachment in attachments:
-            add_acl(self.user, attachment)
+            add_acl(user_acl, attachment)
 
 
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(
         self.assertEqual(