Browse Source

Make tests pass

rafalp 6 years ago
parent
commit
1e22a23c34

+ 1 - 9
misago/acl/migrations/0002_acl_version_tracker.py

@@ -1,11 +1,6 @@
 from django.db import migrations
 from django.db import migrations
 
 
 
 
-def register_acl_version_tracker(apps, schema_editor):
-    from misago.core.migrationutils import cachebuster_register_cache
-    cachebuster_register_cache(apps, "misago_acl")
-
-
 class Migration(migrations.Migration):
 class Migration(migrations.Migration):
     """Superseded by 0004"""
     """Superseded by 0004"""
 
 
@@ -14,7 +9,4 @@ class Migration(migrations.Migration):
         ('misago_core', '0001_initial'),
         ('misago_core', '0001_initial'),
     ]
     ]
 
 
-    operations = [
-        # FIXME: remove this operation
-        migrations.RunPython(register_acl_version_tracker),
-    ]
+    operations = []

+ 17 - 18
misago/admin/views/generic/list.py

@@ -116,15 +116,15 @@ class ListView(AdminView):
                 # So address ball contains copy-friendly link
                 # So address ball contains copy-friendly link
                 refresh_querystring = True
                 refresh_querystring = True
 
 
-        SearchForm = self.get_search_form(request)
-        if SearchForm:
-            filtering_methods = self.get_filtering_methods(request)
+        search_form = self.get_search_form(request)
+        if search_form:
+            filtering_methods = self.get_filtering_methods(request, search_form)
             active_filters = self.get_filtering_method_to_use(filtering_methods)
             active_filters = self.get_filtering_method_to_use(filtering_methods)
             if request.GET.get('clear_filters'):
             if request.GET.get('clear_filters'):
                 # Clear filters from querystring
                 # Clear filters from querystring
                 request.session.pop(self.filters_session_key, None)
                 request.session.pop(self.filters_session_key, None)
                 active_filters = {}
                 active_filters = {}
-            self.apply_filtering_on_context(context, active_filters, SearchForm)
+            self.apply_filtering_on_context(context, active_filters, search_form)
 
 
             if (filtering_methods['GET'] and
             if (filtering_methods['GET'] and
                     filtering_methods['GET'] != filtering_methods['session']):
                     filtering_methods['GET'] != filtering_methods['session']):
@@ -181,12 +181,23 @@ class ListView(AdminView):
     def filters_session_key(self):
     def filters_session_key(self):
         return 'misago_admin_%s_filters' % self.root_link
         return 'misago_admin_%s_filters' % self.root_link
 
 
-    def get_filters_from_GET(self, search_form, request):
+    def get_filtering_methods(self, request, search_form):
+        methods = {
+            'GET': self.get_filters_from_GET(request, search_form),
+            'session': self.get_filters_from_session(request, search_form),
+        }
+
+        if request.GET.get('set_filters'):
+            methods['session'] = {}
+
+        return methods
+
+    def get_filters_from_GET(self, request, search_form):
         form = search_form(request.GET)
         form = search_form(request.GET)
         form.is_valid()
         form.is_valid()
         return self.clean_filtering_data(form.cleaned_data)
         return self.clean_filtering_data(form.cleaned_data)
 
 
-    def get_filters_from_session(self, search_form, request):
+    def get_filters_from_session(self, request, search_form):
         session_filters = request.session.get(self.filters_session_key, {})
         session_filters = request.session.get(self.filters_session_key, {})
         form = search_form(session_filters)
         form = search_form(session_filters)
         form.is_valid()
         form.is_valid()
@@ -198,18 +209,6 @@ class ListView(AdminView):
                 del data[key]
                 del data[key]
         return data
         return data
 
 
-    def get_filtering_methods(self, request):
-        SearchForm = self.get_search_form(request)
-        methods = {
-            'GET': self.get_filters_from_GET(SearchForm, request),
-            'session': self.get_filters_from_session(SearchForm, request),
-        }
-
-        if request.GET.get('set_filters'):
-            methods['session'] = {}
-
-        return methods
-
     def get_filtering_method_to_use(self, methods):
     def get_filtering_method_to_use(self, methods):
         for method in ('GET', 'session'):
         for method in ('GET', 'session'):
             if methods.get(method):
             if methods.get(method):

+ 0 - 3
misago/categories/tests/test_utils.py

@@ -2,7 +2,6 @@ from misago.acl.useracl import get_user_acl
 from misago.categories.models import Category
 from misago.categories.models import Category
 from misago.categories.utils import get_categories_tree, get_category_path
 from misago.categories.utils import get_categories_tree, get_category_path
 from misago.conftest import get_cache_versions
 from misago.conftest import get_cache_versions
-from misago.core import threadstore
 from misago.users.testutils import AuthenticatedUserTestCase
 from misago.users.testutils import AuthenticatedUserTestCase
 
 
 cache_versions = get_cache_versions()
 cache_versions = get_cache_versions()
@@ -33,9 +32,7 @@ class CategoriesUtilsTests(AuthenticatedUserTestCase):
         Category E
         Category E
           + Subcategory F
           + Subcategory F
         """
         """
-
         super().setUp()
         super().setUp()
-        threadstore.clear()
 
 
         self.root = Category.objects.root_category()
         self.root = Category.objects.root_category()
         self.first_category = Category.objects.get(slug='first-category')
         self.first_category = Category.objects.get(slug='first-category')

+ 3 - 9
misago/conf/tests/test_context_processors.py

@@ -2,26 +2,20 @@ from unittest.mock import Mock
 
 
 from django.test import TestCase
 from django.test import TestCase
 
 
-from misago.cache.versions import get_cache_versions
-from misago.core import threadstore
+from misago.conftest import get_cache_versions
 
 
 from misago.conf.context_processors import conf
 from misago.conf.context_processors import conf
 from misago.conf.dynamicsettings import DynamicSettings
 from misago.conf.dynamicsettings import DynamicSettings
 
 
 
 
 class ContextProcessorsTests(TestCase):
 class ContextProcessorsTests(TestCase):
-    def tearDown(self):
-        threadstore.clear()
-
-    def test_db_settings(self):
-        """DBSettings are exposed to templates"""
+    def test_request_settings_are_included_in_template_context(self):
         cache_versions = get_cache_versions()
         cache_versions = get_cache_versions()
         mock_request = Mock(settings=DynamicSettings(cache_versions))
         mock_request = Mock(settings=DynamicSettings(cache_versions))
         context_settings = conf(mock_request)['settings']
         context_settings = conf(mock_request)['settings']
         assert context_settings == mock_request.settings
         assert context_settings == mock_request.settings
 
 
-    def test_preload_settings(self):
-        """site configuration is preloaded by middleware"""
+    def test_settings_are_included_in_frontend_context(self):
         response = self.client.get('/')
         response = self.client.get('/')
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
         self.assertContains(response, '"SETTINGS": {"')
         self.assertContains(response, '"SETTINGS": {"')

+ 0 - 4
misago/conf/tests/test_migrationutils.py

@@ -3,7 +3,6 @@ from django.test import TestCase
 
 
 from misago.conf import migrationutils
 from misago.conf import migrationutils
 from misago.conf.models import SettingsGroup
 from misago.conf.models import SettingsGroup
-from misago.core import threadstore
 
 
 
 
 class DBConfMigrationUtilsTests(TestCase):
 class DBConfMigrationUtilsTests(TestCase):
@@ -36,9 +35,6 @@ class DBConfMigrationUtilsTests(TestCase):
         migrationutils.migrate_settings_group(apps, self.test_group)
         migrationutils.migrate_settings_group(apps, self.test_group)
         self.groups_count = SettingsGroup.objects.count()
         self.groups_count = SettingsGroup.objects.count()
 
 
-    def tearDown(self):
-        threadstore.clear()
-
     def test_get_custom_group_and_settings(self):
     def test_get_custom_group_and_settings(self):
         """tests setup created settings group"""
         """tests setup created settings group"""
         custom_group = migrationutils.get_group(
         custom_group = migrationutils.get_group(

+ 0 - 104
misago/core/cachebuster.py

@@ -1,104 +0,0 @@
-from django.db.models import F
-
-from . import threadstore
-
-
-CACHE_KEY = 'misago_cachebuster'
-
-
-class CacheBusterController(object):
-    def register_cache(self, cache):
-        from .models import CacheVersion
-        CacheVersion.objects.create(cache=cache)
-
-    def unregister_cache(self, cache):
-        from .models import CacheVersion
-
-        try:
-            cache = CacheVersion.objects.get(cache=cache)
-            cache.delete()
-        except CacheVersion.DoesNotExist:
-            raise ValueError('Cache "%s" is not registered' % cache)
-
-    @property
-    def cache(self):
-        return self.read_threadstore()
-
-    def read_threadstore(self):
-        data = threadstore.get(CACHE_KEY, 'nada')
-        if data == 'nada':
-            data = self.read_cache()
-            threadstore.set(CACHE_KEY, data)
-        return data
-
-    def read_cache(self):
-        from .cache import cache as default_cache
-
-        data = default_cache.get(CACHE_KEY, 'nada')
-        if data == 'nada':
-            data = self.read_db()
-            default_cache.set(CACHE_KEY, data)
-        return data
-
-    def read_db(self):
-        from .models import CacheVersion
-
-        data = {}
-        for cache_version in CacheVersion.objects.iterator():
-            data[cache_version.cache] = cache_version.version
-        return data
-
-    def get_cache_version(self, cache):
-        try:
-            return self.cache[cache]
-        except KeyError:
-            raise ValueError('Cache "%s" is not registered' % cache)
-
-    def is_cache_valid(self, cache, version):
-        try:
-            return self.cache[cache] == version
-        except KeyError:
-            raise ValueError('Cache "%s" is not registered' % cache)
-
-    def invalidate_cache(self, cache):
-        from .cache import cache as default_cache
-        from .models import CacheVersion
-
-        self.cache[cache] += 1
-        CacheVersion.objects.filter(cache=cache).update(version=F('version') + 1)
-        default_cache.delete(CACHE_KEY)
-
-    def invalidate_all(self):
-        from .cache import cache as default_cache
-        from .models import CacheVersion
-
-        CacheVersion.objects.update(version=F('version') + 1)
-        default_cache.delete(CACHE_KEY)
-
-
-_controller = CacheBusterController()
-
-
-# Expose controller API
-def register(cache_name):
-    _controller.register_cache(cache_name)
-
-
-def unregister(cache_name):
-    _controller.unregister_cache(cache_name)
-
-
-def get_version(cache_name):
-    return _controller.get_cache_version(cache_name)
-
-
-def is_valid(cache_name, version):
-    return _controller.is_cache_valid(cache_name, version)
-
-
-def invalidate(cache_name):
-    _controller.invalidate_cache(cache_name)
-
-
-def invalidate_all():
-    _controller.invalidate_all()

+ 0 - 24
misago/core/migrationutils.py

@@ -1,24 +0,0 @@
-from .cache import cache as default_cache
-from .cachebuster import CACHE_KEY
-
-
-def _CacheVersion(apps):
-    return apps.get_model('misago_core', 'CacheVersion')
-
-
-def cachebuster_register_cache(apps, cache):
-    _CacheVersion(apps).objects.create(cache=cache)
-
-
-def cachebuster_unregister_cache(apps, cache):
-    CacheVersion = _CacheVersion(apps)
-
-    try:
-        cache = CacheVersion.objects.get(cache=cache)
-        cache.delete()
-    except CacheVersion.DoesNotExist:
-        raise ValueError('Cache "%s" is not registered' % cache)
-
-
-def delete_cachebuster_cache():
-    default_cache.delete(CACHE_KEY)

+ 0 - 74
misago/core/tests/test_cachebuster.py

@@ -1,74 +0,0 @@
-from django.test import TestCase
-
-from misago.core import cachebuster
-from misago.core.models import CacheVersion
-
-
-class CacheBusterTests(TestCase):
-    def test_register_unregister_cache(self):
-        """register and unregister adds/removes cache"""
-        test_cache_name = 'eric_the_fish'
-        with self.assertRaises(CacheVersion.DoesNotExist):
-            CacheVersion.objects.get(cache=test_cache_name)
-
-        cachebuster.register(test_cache_name)
-        CacheVersion.objects.get(cache=test_cache_name)
-
-        cachebuster.unregister(test_cache_name)
-        with self.assertRaises(CacheVersion.DoesNotExist):
-            CacheVersion.objects.get(cache=test_cache_name)
-
-
-class CacheBusterCacheTests(TestCase):
-    def setUp(self):
-        super().setUp()
-
-        self.cache_name = 'eric_the_fish'
-        cachebuster.register(self.cache_name)
-
-    def test_cache_validation(self):
-        """cache correctly validates"""
-        version = cachebuster.get_version(self.cache_name)
-        self.assertEqual(version, 0)
-
-        db_version = CacheVersion.objects.get(cache=self.cache_name).version
-        self.assertEqual(db_version, 0)
-
-        self.assertEqual(db_version, version)
-        self.assertTrue(cachebuster.is_valid(self.cache_name, version))
-        self.assertTrue(cachebuster.is_valid(self.cache_name, db_version))
-
-    def test_cache_invalidation(self):
-        """invalidate has increased valid version number"""
-        db_version = CacheVersion.objects.get(cache=self.cache_name).version
-        cachebuster.invalidate(self.cache_name)
-
-        new_version = cachebuster.get_version(self.cache_name)
-        new_db_version = CacheVersion.objects.get(cache=self.cache_name)
-        new_db_version = new_db_version.version
-
-        self.assertEqual(new_version, 1)
-        self.assertEqual(new_db_version, 1)
-        self.assertEqual(new_version, new_db_version)
-        self.assertFalse(cachebuster.is_valid(self.cache_name, db_version))
-        self.assertTrue(cachebuster.is_valid(self.cache_name, new_db_version))
-
-    def test_cache_invalidation_all(self):
-        """invalidate_all has increased valid version number"""
-        cache_a = "eric_the_halibut"
-        cache_b = "eric_the_crab"
-        cache_c = "eric_the_lion"
-
-        cachebuster.register(cache_a)
-        cachebuster.register(cache_b)
-        cachebuster.register(cache_c)
-
-        cachebuster.invalidate_all()
-
-        new_version_a = CacheVersion.objects.get(cache=cache_a).version
-        new_version_b = CacheVersion.objects.get(cache=cache_b).version
-        new_version_c = CacheVersion.objects.get(cache=cache_c).version
-
-        self.assertEqual(new_version_a, 1)
-        self.assertEqual(new_version_b, 1)
-        self.assertEqual(new_version_c, 1)

+ 0 - 26
misago/core/tests/test_migrationutils.py

@@ -1,26 +0,0 @@
-from django.apps import apps
-from django.test import TestCase
-
-from misago.core import migrationutils
-from misago.core.models import CacheVersion
-
-
-class CacheBusterUtilsTests(TestCase):
-    def test_cachebuster_register_cache(self):
-        """cachebuster_register_cache registers cache on migration successfully"""
-        cache_name = 'eric_licenses'
-        migrationutils.cachebuster_register_cache(apps, cache_name)
-        CacheVersion.objects.get(cache=cache_name)
-
-    def test_cachebuster_unregister_cache(self):
-        """cachebuster_unregister_cache removes cache on migration successfully"""
-        cache_name = 'eric_licenses'
-        migrationutils.cachebuster_register_cache(apps, cache_name)
-        CacheVersion.objects.get(cache=cache_name)
-
-        migrationutils.cachebuster_unregister_cache(apps, cache_name)
-        with self.assertRaises(CacheVersion.DoesNotExist):
-            CacheVersion.objects.get(cache=cache_name)
-
-        with self.assertRaises(ValueError):
-            migrationutils.cachebuster_unregister_cache(apps, cache_name)

+ 0 - 2
misago/threads/tests/test_threadslists.py

@@ -146,8 +146,6 @@ class ThreadsListTestCase(AuthenticatedUserTestCase):
 
 
         self.category_f = Category.objects.get(slug='category-f')
         self.category_f = Category.objects.get(slug='category-f')
 
 
-        self.clear_state()
-
         Category.objects.partial_rebuild(self.root.tree_id)
         Category.objects.partial_rebuild(self.root.tree_id)
 
 
         self.root = Category.objects.root_category()
         self.root = Category.objects.root_category()

+ 0 - 3
misago/threads/tests/test_utils.py

@@ -20,7 +20,6 @@ class AddCategoriesToItemsTests(TestCase):
         Category E
         Category E
           + Subcategory F
           + Subcategory F
         """
         """
-
         super().setUp()
         super().setUp()
 
 
         self.root = Category.objects.root_category()
         self.root = Category.objects.root_category()
@@ -91,8 +90,6 @@ class AddCategoriesToItemsTests(TestCase):
             save=True,
             save=True,
         )
         )
 
 
-        self.clear_state()
-
         Category.objects.partial_rebuild(self.root.tree_id)
         Category.objects.partial_rebuild(self.root.tree_id)
 
 
         self.root = Category.objects.root_category()
         self.root = Category.objects.root_category()

+ 10 - 19
misago/users/forms/admin.py

@@ -7,8 +7,6 @@ from django.utils.translation import ngettext
 
 
 from misago.acl.models import Role
 from misago.acl.models import Role
 from misago.admin.forms import IsoDateTimeField, YesNoSwitch
 from misago.admin.forms import IsoDateTimeField, YesNoSwitch
-from misago.conf import settings
-from misago.core import threadstore
 from misago.core.validators import validate_sluggable
 from misago.core.validators import validate_sluggable
 
 
 from misago.users.models import Ban, DataDownload, Rank
 from misago.users.models import Ban, DataDownload, Rank
@@ -308,7 +306,7 @@ def EditUserFormFactory(FormType, instance, add_is_active_fields=False, add_admi
     return FormType
     return FormType
 
 
 
 
-class SearchUsersFormBase(forms.Form):
+class BaseSearchUsersForm(forms.Form):
     username = forms.CharField(label=_("Username starts with"), required=False)
     username = forms.CharField(label=_("Username starts with"), required=False)
     email = forms.CharField(label=_("E-mail starts with"), required=False)
     email = forms.CharField(label=_("E-mail starts with"), required=False)
     profilefields = forms.CharField(label=_("Profile fields contain"), required=False)
     profilefields = forms.CharField(label=_("Profile fields contain"), required=False)
@@ -349,25 +347,19 @@ class SearchUsersFormBase(forms.Form):
         return queryset
         return queryset
 
 
 
 
-def SearchUsersForm(*args, **kwargs):
+def create_search_users_form():
     """
     """
     Factory that uses cache for ranks and roles,
     Factory that uses cache for ranks and roles,
     and makes those ranks and roles typed choice fields that play nice
     and makes those ranks and roles typed choice fields that play nice
     with passing values via GET
     with passing values via GET
     """
     """
-    ranks_choices = threadstore.get('misago_admin_ranks_choices', 'nada')
-    if ranks_choices == 'nada':
-        ranks_choices = [('', _("All ranks"))]
-        for rank in Rank.objects.order_by('name').iterator():
-            ranks_choices.append((rank.pk, rank.name))
-        threadstore.set('misago_admin_ranks_choices', ranks_choices)
-
-    roles_choices = threadstore.get('misago_admin_roles_choices', 'nada')
-    if roles_choices == 'nada':
-        roles_choices = [('', _("All roles"))]
-        for role in Role.objects.order_by('name').iterator():
-            roles_choices.append((role.pk, role.name))
-        threadstore.set('misago_admin_roles_choices', roles_choices)
+    ranks_choices = [('', _("All ranks"))]
+    for rank in Rank.objects.order_by('name').iterator():
+        ranks_choices.append((rank.pk, rank.name))
+
+    roles_choices = [('', _("All roles"))]
+    for role in Role.objects.order_by('name').iterator():
+        roles_choices.append((role.pk, role.name))
 
 
     extra_fields = {
     extra_fields = {
         'rank': forms.TypedChoiceField(
         'rank': forms.TypedChoiceField(
@@ -384,8 +376,7 @@ def SearchUsersForm(*args, **kwargs):
         )
         )
     }
     }
 
 
-    FinalForm = type('SearchUsersFormFinal', (SearchUsersFormBase, ), extra_fields)
-    return FinalForm(*args, **kwargs)
+    return type('SearchUsersForm', (BaseSearchUsersForm, ), extra_fields)
 
 
 
 
 class RankForm(forms.ModelForm):
 class RankForm(forms.ModelForm):

+ 0 - 11
misago/users/tests/test_activepostersranking.py

@@ -4,8 +4,6 @@ from django.contrib.auth import get_user_model
 from django.utils import timezone
 from django.utils import timezone
 
 
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.core import threadstore
-from misago.core.cache import cache
 from misago.threads.testutils import post_thread
 from misago.threads.testutils import post_thread
 from misago.users.activepostersranking import (
 from misago.users.activepostersranking import (
     build_active_posters_ranking, get_active_posters_ranking)
     build_active_posters_ranking, get_active_posters_ranking)
@@ -19,17 +17,8 @@ class TestActivePostersRanking(AuthenticatedUserTestCase):
     def setUp(self):
     def setUp(self):
         super().setUp()
         super().setUp()
 
 
-        cache.clear()
-        threadstore.clear()
-
         self.category = Category.objects.get(slug='first-category')
         self.category = Category.objects.get(slug='first-category')
 
 
-    def tearDown(self):
-        super().tearDown()
-
-        cache.clear()
-        threadstore.clear()
-
     def test_get_active_posters_ranking(self):
     def test_get_active_posters_ranking(self):
         """get_active_posters_ranking returns list of active posters"""
         """get_active_posters_ranking returns list of active posters"""
         # no posts, empty tanking
         # no posts, empty tanking

+ 19 - 24
misago/users/tests/test_users_api.py

@@ -8,16 +8,13 @@ from django.utils.encoding import smart_str
 
 
 from misago.acl.test import patch_user_acl
 from misago.acl.test import patch_user_acl
 from misago.categories.models import Category
 from misago.categories.models import Category
-from misago.core import threadstore
-from misago.core.cache import cache
 from misago.threads.models import Post, Thread
 from misago.threads.models import Post, Thread
 from misago.threads.testutils import post_thread
 from misago.threads.testutils import post_thread
 from misago.users.activepostersranking import build_active_posters_ranking
 from misago.users.activepostersranking import build_active_posters_ranking
 from misago.users.models import Ban, Rank
 from misago.users.models import Ban, Rank
 from misago.users.testutils import AuthenticatedUserTestCase
 from misago.users.testutils import AuthenticatedUserTestCase
 
 
-
-UserModel = get_user_model()
+User = get_user_model()
 
 
 
 
 class ActivePostersListTests(AuthenticatedUserTestCase):
 class ActivePostersListTests(AuthenticatedUserTestCase):
@@ -25,10 +22,8 @@ class ActivePostersListTests(AuthenticatedUserTestCase):
 
 
     def setUp(self):
     def setUp(self):
         super().setUp()
         super().setUp()
-        self.link = '/api/users/?list=active'
 
 
-        cache.clear()
-        threadstore.clear()
+        self.link = '/api/users/?list=active'
 
 
         self.category = Category.objects.all_categories()[:1][0]
         self.category = Category.objects.all_categories()[:1][0]
         self.category.labels = []
         self.category.labels = []
@@ -86,7 +81,7 @@ class FollowersListTests(AuthenticatedUserTestCase):
 
 
     def test_filled_list(self):
     def test_filled_list(self):
         """user with followers returns 200"""
         """user with followers returns 200"""
-        test_follower = UserModel.objects.create_user(
+        test_follower = User.objects.create_user(
             "TestFollower",
             "TestFollower",
             "test@follower.com",
             "test@follower.com",
             self.USER_PASSWORD,
             self.USER_PASSWORD,
@@ -99,7 +94,7 @@ class FollowersListTests(AuthenticatedUserTestCase):
 
 
     def test_filled_list_search(self):
     def test_filled_list_search(self):
         """followers list is searchable"""
         """followers list is searchable"""
-        test_follower = UserModel.objects.create_user(
+        test_follower = User.objects.create_user(
             "TestFollower",
             "TestFollower",
             "test@follower.com",
             "test@follower.com",
             self.USER_PASSWORD,
             self.USER_PASSWORD,
@@ -132,7 +127,7 @@ class FollowsListTests(AuthenticatedUserTestCase):
 
 
     def test_filled_list(self):
     def test_filled_list(self):
         """user with follows returns 200"""
         """user with follows returns 200"""
-        test_follower = UserModel.objects.create_user(
+        test_follower = User.objects.create_user(
             "TestFollower",
             "TestFollower",
             "test@follower.com",
             "test@follower.com",
             self.USER_PASSWORD,
             self.USER_PASSWORD,
@@ -145,7 +140,7 @@ class FollowsListTests(AuthenticatedUserTestCase):
 
 
     def test_filled_list_search(self):
     def test_filled_list_search(self):
         """follows list is searchable"""
         """follows list is searchable"""
-        test_follower = UserModel.objects.create_user(
+        test_follower = User.objects.create_user(
             "TestFollower",
             "TestFollower",
             "test@follower.com",
             "test@follower.com",
             self.USER_PASSWORD,
             self.USER_PASSWORD,
@@ -214,7 +209,7 @@ class RankListTests(AuthenticatedUserTestCase):
             is_tab=True,
             is_tab=True,
         )
         )
 
 
-        test_user = UserModel.objects.create_user(
+        test_user = User.objects.create_user(
             'Visible',
             'Visible',
             'visible@te.com',
             'visible@te.com',
             'Pass.123',
             'Pass.123',
@@ -255,7 +250,7 @@ class UserRetrieveTests(AuthenticatedUserTestCase):
     def setUp(self):
     def setUp(self):
         super().setUp()
         super().setUp()
 
 
-        self.test_user = UserModel.objects.create_user('Tyrael', 't123@test.com', 'pass123')
+        self.test_user = User.objects.create_user('Tyrael', 't123@test.com', 'pass123')
         self.link = reverse(
         self.link = reverse(
             'misago:api:user-detail', kwargs={
             'misago:api:user-detail', kwargs={
                 'pk': self.test_user.pk,
                 'pk': self.test_user.pk,
@@ -399,7 +394,7 @@ class UserFollowTests(AuthenticatedUserTestCase):
     def setUp(self):
     def setUp(self):
         super().setUp()
         super().setUp()
 
 
-        self.other_user = UserModel.objects.create_user("OtherUser", "other@user.com", "pass123")
+        self.other_user = User.objects.create_user("OtherUser", "other@user.com", "pass123")
 
 
         self.link = '/api/users/%s/follow/' % self.other_user.pk
         self.link = '/api/users/%s/follow/' % self.other_user.pk
 
 
@@ -435,13 +430,13 @@ class UserFollowTests(AuthenticatedUserTestCase):
         response = self.client.post(self.link)
         response = self.client.post(self.link)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
-        user = UserModel.objects.get(pk=self.user.pk)
+        user = User.objects.get(pk=self.user.pk)
         self.assertEqual(user.followers, 0)
         self.assertEqual(user.followers, 0)
         self.assertEqual(user.following, 1)
         self.assertEqual(user.following, 1)
         self.assertEqual(user.follows.count(), 1)
         self.assertEqual(user.follows.count(), 1)
         self.assertEqual(user.followed_by.count(), 0)
         self.assertEqual(user.followed_by.count(), 0)
 
 
-        followed = UserModel.objects.get(pk=self.other_user.pk)
+        followed = User.objects.get(pk=self.other_user.pk)
         self.assertEqual(followed.followers, 1)
         self.assertEqual(followed.followers, 1)
         self.assertEqual(followed.following, 0)
         self.assertEqual(followed.following, 0)
         self.assertEqual(followed.follows.count(), 0)
         self.assertEqual(followed.follows.count(), 0)
@@ -450,13 +445,13 @@ class UserFollowTests(AuthenticatedUserTestCase):
         response = self.client.post(self.link)
         response = self.client.post(self.link)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
-        user = UserModel.objects.get(pk=self.user.pk)
+        user = User.objects.get(pk=self.user.pk)
         self.assertEqual(user.followers, 0)
         self.assertEqual(user.followers, 0)
         self.assertEqual(user.following, 0)
         self.assertEqual(user.following, 0)
         self.assertEqual(user.follows.count(), 0)
         self.assertEqual(user.follows.count(), 0)
         self.assertEqual(user.followed_by.count(), 0)
         self.assertEqual(user.followed_by.count(), 0)
 
 
-        followed = UserModel.objects.get(pk=self.other_user.pk)
+        followed = User.objects.get(pk=self.other_user.pk)
         self.assertEqual(followed.followers, 0)
         self.assertEqual(followed.followers, 0)
         self.assertEqual(followed.following, 0)
         self.assertEqual(followed.following, 0)
         self.assertEqual(followed.follows.count(), 0)
         self.assertEqual(followed.follows.count(), 0)
@@ -469,7 +464,7 @@ class UserBanTests(AuthenticatedUserTestCase):
     def setUp(self):
     def setUp(self):
         super().setUp()
         super().setUp()
 
 
-        self.other_user = UserModel.objects.create_user("OtherUser", "other@user.com", "pass123")
+        self.other_user = User.objects.create_user("OtherUser", "other@user.com", "pass123")
 
 
         self.link = '/api/users/%s/ban/' % self.other_user.pk
         self.link = '/api/users/%s/ban/' % self.other_user.pk
 
 
@@ -584,7 +579,7 @@ class UserDeleteTests(AuthenticatedUserTestCase):
     def setUp(self):
     def setUp(self):
         super().setUp()
         super().setUp()
 
 
-        self.other_user = UserModel.objects.create_user("OtherUser", "other@user.com", "pass123")
+        self.other_user = User.objects.create_user("OtherUser", "other@user.com", "pass123")
 
 
         self.link = '/api/users/%s/delete/' % self.other_user.pk
         self.link = '/api/users/%s/delete/' % self.other_user.pk
 
 
@@ -698,8 +693,8 @@ class UserDeleteTests(AuthenticatedUserTestCase):
         )
         )
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
-        with self.assertRaises(UserModel.DoesNotExist):
-            UserModel.objects.get(pk=self.other_user.pk)
+        with self.assertRaises(User.DoesNotExist):
+            User.objects.get(pk=self.other_user.pk)
 
 
         self.assertEqual(Thread.objects.count(), self.threads)
         self.assertEqual(Thread.objects.count(), self.threads)
         self.assertEqual(Post.objects.count(), self.posts)
         self.assertEqual(Post.objects.count(), self.posts)
@@ -719,8 +714,8 @@ class UserDeleteTests(AuthenticatedUserTestCase):
         )
         )
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
 
 
-        with self.assertRaises(UserModel.DoesNotExist):
-            UserModel.objects.get(pk=self.other_user.pk)
+        with self.assertRaises(User.DoesNotExist):
+            User.objects.get(pk=self.other_user.pk)
 
 
         self.assertEqual(Thread.objects.count(), self.threads + 1)
         self.assertEqual(Thread.objects.count(), self.threads + 1)
         self.assertEqual(Post.objects.count(), self.posts + 2)
         self.assertEqual(Post.objects.count(), self.posts + 2)

+ 7 - 3
misago/users/views/admin/users.py

@@ -13,9 +13,13 @@ from misago.core.mail import mail_users
 from misago.core.pgutils import chunk_queryset
 from misago.core.pgutils import chunk_queryset
 from misago.threads.models import Thread
 from misago.threads.models import Thread
 from misago.users.avatars.dynamic import set_avatar as set_dynamic_avatar
 from misago.users.avatars.dynamic import set_avatar as set_dynamic_avatar
-from misago.users.datadownloads import request_user_data_download, user_has_data_download_request
+from misago.users.datadownloads import (
+    request_user_data_download, user_has_data_download_request
+)
 from misago.users.forms.admin import (
 from misago.users.forms.admin import (
-    BanUsersForm, EditUserForm, EditUserFormFactory, NewUserForm, SearchUsersForm)
+    BanUsersForm, EditUserForm, EditUserFormFactory, NewUserForm,
+    create_search_users_form
+)
 from misago.users.models import Ban
 from misago.users.models import Ban
 from misago.users.profilefields import profilefields
 from misago.users.profilefields import profilefields
 from misago.users.setupnewuser import setup_new_user
 from misago.users.setupnewuser import setup_new_user
@@ -101,7 +105,7 @@ class UsersList(UserAdmin, generic.ListView):
         return qs.select_related('rank')
         return qs.select_related('rank')
 
 
     def get_search_form(self, request):
     def get_search_form(self, request):
-        return SearchUsersForm
+        return create_search_users_form()
 
 
     def action_activate(self, request, users):
     def action_activate(self, request, users):
         inactive_users = []
         inactive_users = []