Browse Source

#702: acl, admin and categories codebase check

Rafał Pitoń 8 years ago
parent
commit
ec2b49c452

+ 8 - 2
misago/acl/forms.py

@@ -31,10 +31,16 @@ def get_permissions_forms(role, data=None):
 
         if FormType:
             if data:
-                perms_forms.append(FormType(data, prefix=extension))
+                perms_forms.append(FormType(
+                    data,
+                    prefix=extension,
+                ))
             else:
                 perms_forms.append(
-                    FormType(initial=role_permissions.get(extension), prefix=extension)
+                    FormType(
+                        initial=role_permissions.get(extension),
+                        prefix=extension,
+                    )
                 )
 
     return perms_forms

+ 1 - 1
misago/acl/panels.py

@@ -7,7 +7,7 @@ class MisagoACLPanel(Panel):
     """
     Panel that displays current user's ACL
     """
-    title = _('Misago User ACL')
+    title = _("Misago User ACL")
     template = 'misago/acl_debug.html'
 
     @property

+ 1 - 1
misago/acl/tests/test_acl_algebra.py

@@ -78,7 +78,7 @@ class SumACLTests(TestCase):
             can_hear=algebra.greater,
             max_speed=algebra.greater,
             min_age=algebra.lower,
-            speed_limit=algebra.greater_or_zero
+            speed_limit=algebra.greater_or_zero,
         )
 
         self.assertEqual(acl['can_see'], 1)

+ 17 - 9
misago/acl/tests/test_roleadmin_views.py

@@ -27,7 +27,7 @@ class RoleAdminViewsTests(AdminTestCase):
 
         response = self.client.post(
             reverse('misago:admin:permissions:users:new'), data=fake_data({
-                'name': 'Test Role'
+                'name': 'Test Role',
             })
         )
         self.assertEqual(response.status_code, 302)
@@ -41,22 +41,26 @@ class RoleAdminViewsTests(AdminTestCase):
         """edit role view has no showstoppers"""
         self.client.post(
             reverse('misago:admin:permissions:users:new'), data=fake_data({
-                'name': 'Test Role'
+                'name': 'Test Role',
             })
         )
 
         test_role = Role.objects.get(name='Test Role')
 
         response = self.client.get(
-            reverse('misago:admin:permissions:users:edit', kwargs={'pk': test_role.pk})
+            reverse('misago:admin:permissions:users:edit', kwargs={
+                'pk': test_role.pk,
+            })
         )
         self.assertEqual(response.status_code, 200)
         self.assertContains(response, 'Test Role')
 
         response = self.client.post(
-            reverse('misago:admin:permissions:users:edit', kwargs={'pk': test_role.pk}),
+            reverse('misago:admin:permissions:users:edit', kwargs={
+                'pk': test_role.pk,
+            }),
             data=fake_data({
-                'name': 'Top Lel'
+                'name': 'Top Lel',
             })
         )
         self.assertEqual(response.status_code, 302)
@@ -70,13 +74,15 @@ class RoleAdminViewsTests(AdminTestCase):
         """users with this role view has no showstoppers"""
         response = self.client.post(
             reverse('misago:admin:permissions:users:new'), data=fake_data({
-                'name': 'Test Role'
+                'name': 'Test Role',
             })
         )
         test_role = Role.objects.get(name='Test Role')
 
         response = self.client.get(
-            reverse('misago:admin:permissions:users:users', kwargs={'pk': test_role.pk})
+            reverse('misago:admin:permissions:users:users', kwargs={
+                'pk': test_role.pk,
+            })
         )
         self.assertEqual(response.status_code, 302)
 
@@ -84,13 +90,15 @@ class RoleAdminViewsTests(AdminTestCase):
         """delete role view has no showstoppers"""
         self.client.post(
             reverse('misago:admin:permissions:users:new'), data=fake_data({
-                'name': 'Test Role'
+                'name': 'Test Role',
             })
         )
 
         test_role = Role.objects.get(name='Test Role')
         response = self.client.post(
-            reverse('misago:admin:permissions:users:delete', kwargs={'pk': test_role.pk})
+            reverse('misago:admin:permissions:users:delete', kwargs={
+                'pk': test_role.pk,
+            })
         )
         self.assertEqual(response.status_code, 302)
 

+ 8 - 6
misago/admin/discoverer.py

@@ -9,9 +9,11 @@ from .urlpatterns import urlpatterns
 def discover_misago_admin():
     for app in apps.get_app_configs():
         module = import_module(app.name)
-        if hasattr(module, 'admin'):
-            admin_module = import_module('%s.admin' % app.name)
-            if hasattr(admin_module, 'MisagoAdminExtension'):
-                extension = getattr(admin_module, 'MisagoAdminExtension')()
-                extension.register_navigation_nodes(site)
-                extension.register_urlpatterns(urlpatterns)
+        if not hasattr(module, 'admin'):
+            continue
+
+        admin_module = import_module('%s.admin' % app.name)
+        if hasattr(admin_module, 'MisagoAdminExtension'):
+            extension = getattr(admin_module, 'MisagoAdminExtension')()
+            extension.register_navigation_nodes(site)
+            extension.register_urlpatterns(urlpatterns)

+ 1 - 2
misago/admin/hierarchy.py

@@ -139,8 +139,7 @@ class AdminHierarchyBuilder(object):
     ):
         if self.nodes_dict:
             raise RuntimeError(
-                "Misago admin site has already been "
-                "initialized. You can't add new nodes to it."
+                "Misago admin site has already been initialized. You can't add new nodes to it."
             )
 
         if after and before:

+ 25 - 10
misago/admin/tests/test_admin_views.py

@@ -49,8 +49,11 @@ class AdminLoginViewTests(TestCase):
     def test_login_returns_200_on_invalid_post(self):
         """form handles invalid data gracefully"""
         response = self.client.post(
-            reverse('misago:admin:index'), data={'username': 'Nope',
-                                                 'password': 'Nope'}
+            reverse('misago:admin:index'),
+            data={
+                'username': 'Nope',
+                'password': 'Nope',
+            },
         )
 
         self.assertContains(response, "Login or password is incorrect.")
@@ -67,8 +70,11 @@ class AdminLoginViewTests(TestCase):
         user.save()
 
         response = self.client.post(
-            reverse('misago:admin:index'), data={'username': 'Bob',
-                                                 'password': 'Pass.123'}
+            reverse('misago:admin:index'),
+            data={
+                'username': 'Bob',
+                'password': 'Pass.123',
+            },
         )
 
         self.assertContains(response, "Your account does not have admin privileges.")
@@ -82,8 +88,11 @@ class AdminLoginViewTests(TestCase):
         user.save()
 
         response = self.client.post(
-            reverse('misago:admin:index'), data={'username': 'Bob',
-                                                 'password': 'Pass.123'}
+            reverse('misago:admin:index'),
+            data={
+                'username': 'Bob',
+                'password': 'Pass.123',
+            },
         )
 
         self.assertContains(response, "Your account does not have admin privileges.")
@@ -97,8 +106,11 @@ class AdminLoginViewTests(TestCase):
         user.save()
 
         response = self.client.post(
-            reverse('misago:admin:index'), data={'username': 'Bob',
-                                                 'password': 'Pass.123'}
+            reverse('misago:admin:index'),
+            data={
+                'username': 'Bob',
+                'password': 'Pass.123',
+            },
         )
 
         self.assertEqual(response.status_code, 302)
@@ -112,8 +124,11 @@ class AdminLoginViewTests(TestCase):
         user.save()
 
         response = self.client.post(
-            reverse('misago:admin:index'), data={'username': 'Bob',
-                                                 'password': 'Pass.123'}
+            reverse('misago:admin:index'),
+            data={
+                'username': 'Bob',
+                'password': 'Pass.123',
+            },
         )
 
         self.assertEqual(response.status_code, 302)

+ 4 - 2
misago/admin/testutils.py

@@ -11,7 +11,9 @@ class AdminTestCase(SuperUserTestCase):
     def login_admin(self, user):
         self.client.post(
             reverse('misago:admin:index'),
-            data={'username': user.email,
-                  'password': self.USER_PASSWORD}
+            data={
+                'username': user.email,
+                'password': self.USER_PASSWORD,
+            }
         )
         self.client.get(reverse('misago:admin:index'))

+ 3 - 1
misago/admin/views/errorpages.py

@@ -34,7 +34,9 @@ def _csrf_failure(request, reason=""):
     if is_admin_session(request):
         update_admin_session(request)
         response = render(
-            request, 'misago/admin/errorpages/csrf_failure_authenticated.html', error_page=True
+            request,
+            'misago/admin/errorpages/csrf_failure_authenticated.html',
+            error_page=True,
         )
     else:
         response = render(request, 'misago/admin/errorpages/csrf_failure.html')

+ 2 - 4
misago/admin/views/generic/formsbuttons.py

@@ -68,8 +68,7 @@ class FormView(TargetedView):
 
     def handle_form(self, form, request):
         raise NotImplementedError(
-            "You have to define your own handle_form method to handle "
-            "form submissions."
+            "You have to define your own handle_form method to handle form submissions."
         )
 
     def real_dispatch(self, request, target):
@@ -104,8 +103,7 @@ class ModelFormView(FormView):
     def handle_form(self, form, request, target):
         form.instance.save()
         if self.message_submit:
-            format = {'name': target.name}
-            messages.success(request, self.message_submit % format)
+            messages.success(request, self.message_submit % {'name': target.name})
 
     def real_dispatch(self, request, target):
         FormType = self.create_form_type(request, target)

+ 3 - 3
misago/categories/admin.py

@@ -49,14 +49,14 @@ class MisagoAdminExtension(object):
             parent='misago:admin',
             before='misago:admin:permissions:users:index',
             namespace='misago:admin:categories',
-            link='misago:admin:categories:nodes:index'
+            link='misago:admin:categories:nodes:index',
         )
         site.add_node(
             name=_("Categories hierarchy"),
             icon='fa fa-sitemap',
             parent='misago:admin:categories',
             namespace='misago:admin:categories:nodes',
-            link='misago:admin:categories:nodes:index'
+            link='misago:admin:categories:nodes:index',
         )
         site.add_node(
             name=_("Category roles"),
@@ -64,5 +64,5 @@ class MisagoAdminExtension(object):
             parent='misago:admin:permissions',
             after='misago:admin:permissions:users:index',
             namespace='misago:admin:permissions:categories',
-            link='misago:admin:permissions:categories:index'
+            link='misago:admin:permissions:categories:index',
         )

+ 19 - 24
misago/categories/forms.py

@@ -60,47 +60,42 @@ class CategoryFormBase(forms.ModelForm):
         max_length=2048,
         required=False,
         widget=forms.Textarea(attrs={'rows': 3}),
-        help_text=_("Optional description explaining category intented purpose.")
+        help_text=_("Optional description explaining category intented purpose."),
     )
     css_class = forms.CharField(
         label=_("CSS class"),
         required=False,
         help_text=_(
-            "Optional CSS class used to customize this category "
-            "appearance from templates."
-        )
+            "Optional CSS class used to customize this category appearance from templates."
+        ),
     )
     is_closed = YesNoSwitch(
         label=_("Closed category"),
         required=False,
-        help_text=_("Only members with valid permissions can post in "
-                    "closed categories.")
+        help_text=_("Only members with valid permissions can post in closed categories."),
     )
     css_class = forms.CharField(
         label=_("CSS class"),
         required=False,
         help_text=_(
-            "Optional CSS class used to customize this category "
-            "appearance from templates."
-        )
+            "Optional CSS class used to customize this category appearance from templates."
+        ),
     )
     prune_started_after = forms.IntegerField(
         label=_("Thread age"),
         min_value=0,
         help_text=_(
-            "Prune thread if number of days since its creation is "
-            "greater than specified. Enter 0 to disable this "
-            "pruning criteria."
-        )
+            "Prune thread if number of days since its creation is greater than specified. "
+            "Enter 0 to disable this pruning criteria."
+        ),
     )
     prune_replied_after = forms.IntegerField(
         label=_("Last reply"),
         min_value=0,
         help_text=_(
-            "Prune thread if number of days since last reply is "
-            "greater than specified. Enter 0 to disable this "
-            "pruning criteria."
-        )
+            "Prune thread if number of days since last reply is greater than specified. "
+            "Enter 0 to disable this pruning criteria."
+        ),
     )
 
     class Meta:
@@ -149,7 +144,7 @@ def CategoryFormFactory(instance):
                     label=_("Parent category"),
                     queryset=parent_queryset,
                     initial=instance.parent,
-                    empty_label=None
+                    empty_label=None,
                 ),
             'copy_permissions':
                 AdminCategoryChoiceField(
@@ -160,7 +155,7 @@ def CategoryFormFactory(instance):
                     ),
                     queryset=Category.objects.all_categories(),
                     empty_label=_("Don't copy permissions"),
-                    required=False
+                    required=False,
                 ),
             'archive_pruned_in':
                 AdminCategoryChoiceField(
@@ -171,7 +166,7 @@ def CategoryFormFactory(instance):
                     ),
                     queryset=Category.objects.all_categories(),
                     empty_label=_("Don't archive pruned threads"),
-                    required=False
+                    required=False,
                 ),
         }
     )
@@ -211,7 +206,7 @@ def DeleteFormFactory(instance):
                 queryset=content_queryset,
                 initial=instance.parent,
                 empty_label=_('Delete with category'),
-                required=False
+                required=False,
             )
     }
 
@@ -225,7 +220,7 @@ def DeleteFormFactory(instance):
             label=_("Move child categories to"),
             queryset=children_queryset,
             empty_label=_('Delete with category'),
-            required=False
+            required=False,
         )
 
     return type('DeleteCategoryFormFinal', (DeleteCategoryFormBase, ), fields)
@@ -249,7 +244,7 @@ def RoleCategoryACLFormFactory(category, category_roles, selected_role):
                 required=False,
                 queryset=category_roles,
                 initial=selected_role,
-                empty_label=_("No access")
+                empty_label=_("No access"),
             )
     }
 
@@ -266,7 +261,7 @@ def CategoryRolesACLFormFactory(role, category_roles, selected_role):
                 required=False,
                 queryset=category_roles,
                 initial=selected_role,
-                empty_label=_("No access")
+                empty_label=_("No access"),
             )
     }
 

+ 13 - 4
misago/categories/models.py

@@ -60,7 +60,12 @@ class CategoryManager(TreeManager):
 
 @python_2_unicode_compatible
 class Category(MPTTModel):
-    parent = TreeForeignKey('self', null=True, blank=True, related_name='children')
+    parent = TreeForeignKey(
+        'self',
+        null=True,
+        blank=True,
+        related_name='children',
+    )
     special_role = models.CharField(max_length=255, null=True, blank=True)
     name = models.CharField(max_length=255)
     slug = models.CharField(max_length=255)
@@ -74,7 +79,7 @@ class Category(MPTTModel):
         related_name='+',
         null=True,
         blank=True,
-        on_delete=models.SET_NULL
+        on_delete=models.SET_NULL,
     )
     last_thread_title = models.CharField(max_length=255, null=True, blank=True)
     last_thread_slug = models.CharField(max_length=255, null=True, blank=True)
@@ -83,14 +88,18 @@ class Category(MPTTModel):
         related_name='+',
         null=True,
         blank=True,
-        on_delete=models.SET_NULL
+        on_delete=models.SET_NULL,
     )
     last_poster_name = models.CharField(max_length=255, null=True, blank=True)
     last_poster_slug = models.CharField(max_length=255, null=True, blank=True)
     prune_started_after = models.PositiveIntegerField(default=0)
     prune_replied_after = models.PositiveIntegerField(default=0)
     archive_pruned_in = models.ForeignKey(
-        'self', related_name='pruned_archive', null=True, blank=True, on_delete=models.SET_NULL
+        'self',
+        related_name='pruned_archive',
+        null=True,
+        blank=True,
+        on_delete=models.SET_NULL,
     )
     css_class = models.CharField(max_length=255, null=True, blank=True)
 

+ 2 - 2
misago/categories/permissions.py

@@ -84,7 +84,7 @@ def build_category_acl(acl, category, categories_roles, key_name):
         roles=category_roles,
         key=key_name,
         can_see=algebra.greater,
-        can_browse=algebra.greater
+        can_browse=algebra.greater,
     )
 
     if final_acl['can_see']:
@@ -115,7 +115,7 @@ def serialize_categories_alcs(serialized_acl):
                 'can_reply_threads': acl.get('can_reply_threads', False),
                 'can_pin_threads': acl.get('can_pin_threads', 0),
                 'can_hide_threads': acl.get('can_hide_threads', 0),
-                'can_close_threads': acl.get('can_close_threads', False)
+                'can_close_threads': acl.get('can_close_threads', False),
             })
     serialized_acl['categories'] = categories_acl
 

+ 6 - 3
misago/categories/serializers.py

@@ -19,7 +19,9 @@ def last_activity_detail(f):
             return None
 
         acl = self.get_acl(obj)
-        if not all((acl.get('can_see'), acl.get('can_browse'), acl.get('can_see_all_threads'))):
+        tested_acls = (acl.get('can_see'), acl.get('can_browse'), acl.get('can_see_all_threads'), )
+
+        if not all(tested_acls):
             return None
 
         return f(self, obj)
@@ -84,10 +86,11 @@ class CategorySerializer(serializers.ModelSerializer, MutableFields):
     def get_last_poster_url(self, obj):
         if obj.last_poster_id:
             return reverse(
-                'misago:user', kwargs={
+                'misago:user',
+                kwargs={
                     'slug': obj.last_poster_slug,
                     'pk': obj.last_poster_id,
-                }
+                },
             )
         else:
             return None

+ 2 - 4
misago/categories/signals.py

@@ -7,13 +7,11 @@ from .models import Category
 
 delete_category_content = Signal()
 move_category_content = Signal(providing_args=["new_category"])
-"""
-Signal handlers
-"""
 
 
 @receiver(username_changed)
 def update_usernames(sender, **kwargs):
     Category.objects.filter(last_poster=sender).update(
-        last_poster_name=sender.username, last_poster_slug=sender.slug
+        last_poster_name=sender.username,
+        last_poster_slug=sender.slug,
     )

+ 67 - 33
misago/categories/tests/test_categories_admin_views.py

@@ -79,7 +79,7 @@ class CategoryAdminViewsTests(CategoryAdminTestCate):
                 'new_parent': root.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         self.assertEqual(response.status_code, 302)
 
@@ -102,7 +102,7 @@ class CategoryAdminViewsTests(CategoryAdminTestCate):
                 'new_parent': root.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         self.assertEqual(response.status_code, 302)
 
@@ -123,7 +123,7 @@ class CategoryAdminViewsTests(CategoryAdminTestCate):
                 'copy_permissions': test_category.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         self.assertEqual(response.status_code, 302)
 
@@ -147,12 +147,16 @@ class CategoryAdminViewsTests(CategoryAdminTestCate):
         first_category = Category.objects.get(slug='first-category')
 
         response = self.client.get(
-            reverse('misago:admin:categories:nodes:edit', kwargs={'pk': private_threads.pk})
+            reverse('misago:admin:categories:nodes:edit', kwargs={
+                'pk': private_threads.pk,
+            })
         )
         self.assertEqual(response.status_code, 302)
 
         response = self.client.get(
-            reverse('misago:admin:categories:nodes:edit', kwargs={'pk': root.pk})
+            reverse('misago:admin:categories:nodes:edit', kwargs={
+                'pk': root.pk,
+            })
         )
         self.assertEqual(response.status_code, 302)
 
@@ -164,27 +168,31 @@ class CategoryAdminViewsTests(CategoryAdminTestCate):
                 'new_parent': root.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         self.assertEqual(response.status_code, 302)
 
         test_category = Category.objects.get(slug='test-category')
 
         response = self.client.get(
-            reverse('misago:admin:categories:nodes:edit', kwargs={'pk': test_category.pk})
+            reverse('misago:admin:categories:nodes:edit', kwargs={
+                'pk': test_category.pk,
+            })
         )
 
         self.assertContains(response, 'Test Category')
 
         response = self.client.post(
-            reverse('misago:admin:categories:nodes:edit', kwargs={'pk': test_category.pk}),
+            reverse('misago:admin:categories:nodes:edit', kwargs={
+                'pk': test_category.pk,
+            }),
             data={
                 'name': 'Test Category Edited',
                 'new_parent': root.pk,
                 'role': 'category',
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         self.assertEqual(response.status_code, 302)
 
@@ -198,14 +206,16 @@ class CategoryAdminViewsTests(CategoryAdminTestCate):
         self.assertContains(response, 'Test Category Edited')
 
         response = self.client.post(
-            reverse('misago:admin:categories:nodes:edit', kwargs={'pk': test_category.pk}),
+            reverse('misago:admin:categories:nodes:edit', kwargs={
+                'pk': test_category.pk,
+            }),
             data={
                 'name': 'Test Category Edited',
                 'new_parent': first_category.pk,
                 'role': 'category',
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         self.assertEqual(response.status_code, 302)
 
@@ -230,7 +240,7 @@ class CategoryAdminViewsTests(CategoryAdminTestCate):
                 'new_parent': root.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         category_a = Category.objects.get(slug='category-a')
 
@@ -241,12 +251,14 @@ class CategoryAdminViewsTests(CategoryAdminTestCate):
                 'new_parent': root.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         category_b = Category.objects.get(slug='category-b')
 
         response = self.client.post(
-            reverse('misago:admin:categories:nodes:up', kwargs={'pk': category_b.pk})
+            reverse('misago:admin:categories:nodes:up', kwargs={
+                'pk': category_b.pk,
+            })
         )
         self.assertEqual(response.status_code, 302)
 
@@ -258,7 +270,9 @@ class CategoryAdminViewsTests(CategoryAdminTestCate):
         ])
 
         response = self.client.post(
-            reverse('misago:admin:categories:nodes:up', kwargs={'pk': category_b.pk})
+            reverse('misago:admin:categories:nodes:up', kwargs={
+                'pk': category_b.pk,
+            })
         )
         self.assertEqual(response.status_code, 302)
 
@@ -270,7 +284,9 @@ class CategoryAdminViewsTests(CategoryAdminTestCate):
         ])
 
         response = self.client.post(
-            reverse('misago:admin:categories:nodes:down', kwargs={'pk': category_b.pk})
+            reverse('misago:admin:categories:nodes:down', kwargs={
+                'pk': category_b.pk,
+            })
         )
         self.assertEqual(response.status_code, 302)
 
@@ -282,7 +298,9 @@ class CategoryAdminViewsTests(CategoryAdminTestCate):
         ])
 
         response = self.client.post(
-            reverse('misago:admin:categories:nodes:down', kwargs={'pk': category_b.pk})
+            reverse('misago:admin:categories:nodes:down', kwargs={
+                'pk': category_b.pk,
+            })
         )
         self.assertEqual(response.status_code, 302)
 
@@ -294,7 +312,9 @@ class CategoryAdminViewsTests(CategoryAdminTestCate):
         ])
 
         response = self.client.post(
-            reverse('misago:admin:categories:nodes:down', kwargs={'pk': category_b.pk})
+            reverse('misago:admin:categories:nodes:down', kwargs={
+                'pk': category_b.pk,
+            })
         )
         self.assertEqual(response.status_code, 302)
 
@@ -331,7 +351,7 @@ class CategoryAdminDeleteViewTests(CategoryAdminTestCate):
                 'new_parent': self.root.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
 
         self.client.post(
@@ -341,7 +361,7 @@ class CategoryAdminDeleteViewTests(CategoryAdminTestCate):
                 'new_parent': self.root.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
 
         self.category_a = Category.objects.get(slug='category-a')
@@ -354,7 +374,7 @@ class CategoryAdminDeleteViewTests(CategoryAdminTestCate):
                 'new_parent': self.category_a.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         self.category_b = Category.objects.get(slug='category-b')
 
@@ -365,7 +385,7 @@ class CategoryAdminDeleteViewTests(CategoryAdminTestCate):
                 'new_parent': self.category_b.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         self.category_c = Category.objects.get(slug='subcategory-c')
 
@@ -376,7 +396,7 @@ class CategoryAdminDeleteViewTests(CategoryAdminTestCate):
                 'new_parent': self.category_b.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         self.category_d = Category.objects.get(slug='subcategory-d')
 
@@ -387,7 +407,7 @@ class CategoryAdminDeleteViewTests(CategoryAdminTestCate):
                 'new_parent': self.category_e.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         self.category_f = Category.objects.get(slug='category-f')
 
@@ -398,16 +418,20 @@ class CategoryAdminDeleteViewTests(CategoryAdminTestCate):
         self.assertEqual(Thread.objects.count(), 10)
 
         response = self.client.get(
-            reverse('misago:admin:categories:nodes:delete', kwargs={'pk': self.category_b.pk})
+            reverse('misago:admin:categories:nodes:delete', kwargs={
+                'pk': self.category_b.pk,
+            })
         )
         self.assertEqual(response.status_code, 200)
 
         response = self.client.post(
-            reverse('misago:admin:categories:nodes:delete', kwargs={'pk': self.category_b.pk}),
+            reverse('misago:admin:categories:nodes:delete', kwargs={
+                'pk': self.category_b.pk,
+            }),
             data={
                 'move_children_to': self.category_e.pk,
                 'move_threads_to': self.category_d.pk,
-            }
+            },
         )
         self.assertEqual(response.status_code, 302)
         self.assertEqual(Category.objects.all_categories().count(), 6)
@@ -429,14 +453,20 @@ class CategoryAdminDeleteViewTests(CategoryAdminTestCate):
             testutils.post_thread(self.category_b)
 
         response = self.client.get(
-            reverse('misago:admin:categories:nodes:delete', kwargs={'pk': self.category_b.pk})
+            reverse('misago:admin:categories:nodes:delete', kwargs={
+                'pk': self.category_b.pk,
+            })
         )
         self.assertEqual(response.status_code, 200)
 
         response = self.client.post(
-            reverse('misago:admin:categories:nodes:delete', kwargs={'pk': self.category_b.pk}),
-            data={'move_children_to': '',
-                  'move_threads_to': ''}
+            reverse('misago:admin:categories:nodes:delete', kwargs={
+                'pk': self.category_b.pk,
+            }),
+            data={
+                'move_children_to': '',
+                'move_threads_to': '',
+            }
         )
         self.assertEqual(response.status_code, 302)
 
@@ -458,12 +488,16 @@ class CategoryAdminDeleteViewTests(CategoryAdminTestCate):
         self.assertEqual(Thread.objects.count(), 10)
 
         response = self.client.get(
-            reverse('misago:admin:categories:nodes:delete', kwargs={'pk': self.category_d.pk})
+            reverse('misago:admin:categories:nodes:delete', kwargs={
+                'pk': self.category_d.pk,
+            })
         )
         self.assertEqual(response.status_code, 200)
 
         response = self.client.post(
-            reverse('misago:admin:categories:nodes:delete', kwargs={'pk': self.category_d.pk}),
+            reverse('misago:admin:categories:nodes:delete', kwargs={
+                'pk': self.category_d.pk,
+            }),
             data={
                 'move_children_to': '',
                 'move_threads_to': '',

+ 54 - 32
misago/categories/tests/test_permissions_admin_views.py

@@ -31,8 +31,8 @@ class CategoryRoleAdminViewsTests(AdminTestCase):
         response = self.client.post(
             reverse('misago:admin:permissions:categories:new'),
             data=fake_data({
-                'name': 'Test CategoryRole'
-            })
+                'name': 'Test CategoryRole',
+            }),
         )
         self.assertEqual(response.status_code, 302)
 
@@ -45,22 +45,26 @@ class CategoryRoleAdminViewsTests(AdminTestCase):
         self.client.post(
             reverse('misago:admin:permissions:categories:new'),
             data=fake_data({
-                'name': 'Test CategoryRole'
-            })
+                'name': 'Test CategoryRole',
+            }),
         )
 
         test_role = CategoryRole.objects.get(name='Test CategoryRole')
 
         response = self.client.get(
-            reverse('misago:admin:permissions:categories:edit', kwargs={'pk': test_role.pk})
+            reverse('misago:admin:permissions:categories:edit', kwargs={
+                'pk': test_role.pk,
+            })
         )
         self.assertContains(response, 'Test CategoryRole')
 
         response = self.client.post(
-            reverse('misago:admin:permissions:categories:edit', kwargs={'pk': test_role.pk}),
+            reverse('misago:admin:permissions:categories:edit', kwargs={
+                'pk': test_role.pk,
+            }),
             data=fake_data({
-                'name': 'Top Lel'
-            })
+                'name': 'Top Lel',
+            }),
         )
         self.assertEqual(response.status_code, 302)
 
@@ -73,13 +77,15 @@ class CategoryRoleAdminViewsTests(AdminTestCase):
         self.client.post(
             reverse('misago:admin:permissions:categories:new'),
             data=fake_data({
-                'name': 'Test CategoryRole'
-            })
+                'name': 'Test CategoryRole',
+            }),
         )
 
         test_role = CategoryRole.objects.get(name='Test CategoryRole')
         response = self.client.post(
-            reverse('misago:admin:permissions:categories:delete', kwargs={'pk': test_role.pk})
+            reverse('misago:admin:permissions:categories:delete', kwargs={
+                'pk': test_role.pk,
+            })
         )
         self.assertEqual(response.status_code, 302)
 
@@ -108,7 +114,7 @@ class CategoryRoleAdminViewsTests(AdminTestCase):
                 'new_parent': root.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         test_category = Category.objects.get(slug='category-a')
 
@@ -131,14 +137,14 @@ class CategoryRoleAdminViewsTests(AdminTestCase):
         self.client.post(
             reverse('misago:admin:permissions:categories:new'),
             data=fake_data({
-                'name': 'Test Comments'
-            })
+                'name': 'Test Comments',
+            }),
         )
         self.client.post(
             reverse('misago:admin:permissions:categories:new'),
             data=fake_data({
-                'name': 'Test Full'
-            })
+                'name': 'Test Full',
+            }),
         )
 
         role_comments = CategoryRole.objects.get(name='Test Comments')
@@ -148,7 +154,11 @@ class CategoryRoleAdminViewsTests(AdminTestCase):
         """
         # See if form page is rendered
         response = self.client.get(
-            reverse('misago:admin:categories:nodes:permissions', kwargs={'pk': test_category.pk})
+            reverse(
+                'misago:admin:categories:nodes:permissions', kwargs={
+                    'pk': test_category.pk,
+                }
+            )
         )
         self.assertContains(response, test_category.name)
         self.assertContains(response, test_role_a.name)
@@ -158,11 +168,15 @@ class CategoryRoleAdminViewsTests(AdminTestCase):
 
         # Assign roles to categories
         response = self.client.post(
-            reverse('misago:admin:categories:nodes:permissions', kwargs={'pk': test_category.pk}),
+            reverse(
+                'misago:admin:categories:nodes:permissions', kwargs={
+                    'pk': test_category.pk,
+                }
+            ),
             data={
                 ('%s-category_role' % test_role_a.pk): role_full.pk,
                 ('%s-category_role' % test_role_b.pk): role_comments.pk,
-            }
+            },
         )
         self.assertEqual(response.status_code, 302)
 
@@ -188,7 +202,9 @@ class CategoryRoleAdminViewsTests(AdminTestCase):
 
         self.assertEqual(Category.objects.count(), 2)
         response = self.client.get(
-            reverse('misago:admin:permissions:users:categories', kwargs={'pk': test_role.pk})
+            reverse('misago:admin:permissions:users:categories', kwargs={
+                'pk': test_role.pk,
+            })
         )
         self.assertEqual(response.status_code, 302)
         """
@@ -207,7 +223,7 @@ class CategoryRoleAdminViewsTests(AdminTestCase):
                 'new_parent': root.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         self.client.post(
             reverse('misago:admin:categories:nodes:new'),
@@ -216,7 +232,7 @@ class CategoryRoleAdminViewsTests(AdminTestCase):
                 'new_parent': root.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
 
         category_a = Category.objects.get(slug='category-a')
@@ -229,7 +245,7 @@ class CategoryRoleAdminViewsTests(AdminTestCase):
                 'new_parent': category_a.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         category_b = Category.objects.get(slug='category-b')
 
@@ -240,7 +256,7 @@ class CategoryRoleAdminViewsTests(AdminTestCase):
                 'new_parent': category_c.pk,
                 'prune_started_after': 0,
                 'prune_replied_after': 0,
-            }
+            },
         )
         category_d = Category.objects.get(slug='category-d')
 
@@ -248,7 +264,9 @@ class CategoryRoleAdminViewsTests(AdminTestCase):
 
         # See if form page is rendered
         response = self.client.get(
-            reverse('misago:admin:permissions:users:categories', kwargs={'pk': test_role.pk})
+            reverse('misago:admin:permissions:users:categories', kwargs={
+                'pk': test_role.pk,
+            })
         )
         self.assertContains(response, category_a.name)
         self.assertContains(response, category_b.name)
@@ -259,35 +277,39 @@ class CategoryRoleAdminViewsTests(AdminTestCase):
         self.client.post(
             reverse('misago:admin:permissions:categories:new'),
             data=fake_data({
-                'name': 'Test Comments'
-            })
+                'name': 'Test Comments',
+            }),
         )
         role_comments = CategoryRole.objects.get(name='Test Comments')
 
         self.client.post(
             reverse('misago:admin:permissions:categories:new'),
             data=fake_data({
-                'name': 'Test Full'
-            })
+                'name': 'Test Full',
+            }),
         )
         role_full = CategoryRole.objects.get(name='Test Full')
 
         # See if form contains those roles
         response = self.client.get(
-            reverse('misago:admin:permissions:users:categories', kwargs={'pk': test_role.pk})
+            reverse('misago:admin:permissions:users:categories', kwargs={
+                'pk': test_role.pk,
+            })
         )
         self.assertContains(response, role_comments.name)
         self.assertContains(response, role_full.name)
 
         # Assign roles to categories
         response = self.client.post(
-            reverse('misago:admin:permissions:users:categories', kwargs={'pk': test_role.pk}),
+            reverse('misago:admin:permissions:users:categories', kwargs={
+                'pk': test_role.pk,
+            }),
             data={
                 ('%s-role' % category_a.pk): role_comments.pk,
                 ('%s-role' % category_b.pk): role_comments.pk,
                 ('%s-role' % category_c.pk): role_full.pk,
                 ('%s-role' % category_d.pk): role_full.pk,
-            }
+            },
         )
         self.assertEqual(response.status_code, 302)
 

+ 18 - 6
misago/categories/tests/test_utils.py

@@ -29,13 +29,17 @@ class CategoriesUtilsTests(AuthenticatedUserTestCase):
             name='Category A',
             slug='category-a',
         ).insert_at(
-            self.root, position='last-child', save=True
+            self.root,
+            position='last-child',
+            save=True,
         )
         Category(
             name='Category E',
             slug='category-e',
         ).insert_at(
-            self.root, position='last-child', save=True
+            self.root,
+            position='last-child',
+            save=True,
         )
 
         self.category_a = Category.objects.get(slug='category-a')
@@ -44,7 +48,9 @@ class CategoriesUtilsTests(AuthenticatedUserTestCase):
             name='Category B',
             slug='category-b',
         ).insert_at(
-            self.category_a, position='last-child', save=True
+            self.category_a,
+            position='last-child',
+            save=True,
         )
 
         self.category_b = Category.objects.get(slug='category-b')
@@ -53,13 +59,17 @@ class CategoriesUtilsTests(AuthenticatedUserTestCase):
             name='Subcategory C',
             slug='subcategory-c',
         ).insert_at(
-            self.category_b, position='last-child', save=True
+            self.category_b,
+            position='last-child',
+            save=True,
         )
         Category(
             name='Subcategory D',
             slug='subcategory-d',
         ).insert_at(
-            self.category_b, position='last-child', save=True
+            self.category_b,
+            position='last-child',
+            save=True,
         )
 
         self.category_e = Category.objects.get(slug='category-e')
@@ -67,7 +77,9 @@ class CategoriesUtilsTests(AuthenticatedUserTestCase):
             name='Subcategory F',
             slug='subcategory-f',
         ).insert_at(
-            self.category_e, position='last-child', save=True
+            self.category_e,
+            position='last-child',
+            save=True,
         )
 
         categories_acl = {'categories': {}, 'visible_categories': []}

+ 1 - 1
misago/categories/views/categorieslist.py

@@ -10,7 +10,7 @@ def categories(request):
 
     request.frontend_context.update({
         'CATEGORIES': CategorySerializer(categories_tree, many=True).data,
-        'CATEGORIES_API': reverse('misago:api:category-list')
+        'CATEGORIES_API': reverse('misago:api:category-list'),
     })
 
     return render(request, 'misago/categories/list.html', {

+ 13 - 16
misago/categories/views/permsadmin.py

@@ -58,11 +58,12 @@ class RoleFormMixin(object):
                 form.add_error(None, _("Form contains errors."))
 
         return self.render(
-            request, {
+            request,
+            {
                 'form': form,
                 'target': target,
                 'perms_forms': perms_forms,
-            }
+            },
         )
 
 
@@ -86,13 +87,10 @@ class DeleteCategoryRole(CategoryRoleAdmin, generic.ButtonView):
         messages.success(request, message % {'name': target.name})
 
 
-"""
-Create category roles view for assinging roles to category,
-add link to it in categories list
-"""
-
-
 class CategoryPermissions(CategoryAdmin, generic.ModelFormView):
+    """
+    Category roles view for assinging roles to category, add link to it in categories list
+    """
     templates_dir = 'misago/admin/categoryroles'
     template = 'categoryroles.html'
 
@@ -126,7 +124,7 @@ class CategoryPermissions(CategoryAdmin, generic.ModelFormView):
                         RoleCategoryACL(
                             role=form.role,
                             category=target,
-                            category_role=form.cleaned_data['category_role']
+                            category_role=form.cleaned_data['category_role'],
                         )
                     )
             if new_permissions:
@@ -151,15 +149,14 @@ CategoriesList.add_item_action(
     name=_("Category permissions"),
     icon='fa fa-adjust',
     link='misago:admin:categories:nodes:permissions',
-    style='success'
+    style='success',
 )
-"""
-Create role categories view for assinging categories to role,
-add link to it in user roles list
-"""
 
 
 class RoleCategoriesACL(RoleAdmin, generic.ModelFormView):
+    """
+    Role categories view for assinging categories to role, add link to it in user roles list
+    """
     templates_dir = 'misago/admin/categoryroles'
     template = 'rolecategories.html'
 
@@ -197,7 +194,7 @@ class RoleCategoriesACL(RoleAdmin, generic.ModelFormView):
                         RoleCategoryACL(
                             role=target,
                             category=form.category,
-                            category_role=form.cleaned_data['role']
+                            category_role=form.cleaned_data['role'],
                         )
                     )
             if new_permissions:
@@ -222,5 +219,5 @@ RolesList.add_item_action(
     name=_("Categories permissions"),
     icon='fa fa-comments-o',
     link='misago:admin:permissions:users:categories',
-    style='success'
+    style='success',
 )