Browse Source

Added tests harness for bans.

Rafał Pitoń 11 years ago
parent
commit
424132b0b1

+ 3 - 3
misago/faker/management/commands/createfakebans.py

@@ -6,7 +6,7 @@ from django.core.exceptions import ValidationError
 from django.core.management.base import BaseCommand
 from django.db import IntegrityError
 from django.utils import timezone
-from misago.users.models import Ban, BAN_NAME, BAN_EMAIL, BAN_IP
+from misago.users.models import Ban, BAN_USERNAME, BAN_EMAIL, BAN_IP
 
 
 def fake_username_ban(fake):
@@ -66,7 +66,7 @@ def fake_ip_ban(fake):
 
 
 def create_fake_test(fake, test_type):
-    if test_type == BAN_NAME:
+    if test_type == BAN_USERNAME:
         return fake_username_ban(fake)
     elif test_type == BAN_EMAIL:
         return fake_email_ban(fake)
@@ -88,7 +88,7 @@ class Command(BaseCommand):
 
         created_count = 0
         for i in xrange(fake_bans_to_create):
-            ban = Ban(test=random.randint(BAN_NAME, BAN_IP))
+            ban = Ban(test=random.randint(BAN_USERNAME, BAN_IP))
             ban.banned_value = create_fake_test(fake, ban.test)
 
             if random.randint(0, 10) == 0:

+ 1 - 1
misago/users/admin.py

@@ -1,6 +1,6 @@
 from django.conf.urls import url
 from django.utils.translation import ugettext_lazy as _
-from misago.users.views.bansadmin import BansList, NewBan, EditBan, DeleteBan
+from misago.users.views.banadmin import BansList, NewBan, EditBan, DeleteBan
 from misago.users.views.rankadmin import (RanksList, NewRank, EditRank,
                                           DeleteRank, MoveUpRank, MoveDownRank,
                                           DefaultRank)

+ 1 - 1
misago/users/migrations/0001_initial.py

@@ -97,7 +97,7 @@ class Migration(migrations.Migration):
                 ('user_message', models.TextField(null=True, blank=True)),
                 ('staff_message', models.TextField(null=True, blank=True)),
                 ('valid_until', models.DateField(null=True, blank=True, db_index=True)),
-                ('is_valid', models.BooleanField(default=False, db_index=True)),
+                ('is_valid', models.BooleanField(default=True, db_index=True)),
             ],
             bases=(models.Model,),
         ),

+ 11 - 10
misago/users/models.py

@@ -276,13 +276,13 @@ class Rank(models.Model):
 """
 Bans
 """
-BAN_NAME = 0
+BAN_USERNAME = 0
 BAN_EMAIL = 1
 BAN_IP = 2
 
 
 BANS_CHOICES = (
-    (BAN_NAME, _('Username')),
+    (BAN_USERNAME, _('Username')),
     (BAN_EMAIL, _('E-mail address')),
     (BAN_IP, _('IP Address')),
 )
@@ -303,7 +303,7 @@ class BansManager(models.Manager):
 
         if username:
             username = username.lower()
-            tests.append(BAN_NAME)
+            tests.append(BAN_USERNAME)
         if email:
             email = email.lower()
             tests.append(BAN_EMAIL)
@@ -317,22 +317,23 @@ class BansManager(models.Manager):
             queryset = queryset.filter(test__in=tests)
 
         for ban in queryset.order_by('-id').iterator():
-            if username and ban.test == BAN_NAME and ban.test_value(username):
+            if (ban.test == BAN_USERNAME and username and
+                    ban.test_value(username)):
                 return ban
-            elif email and ban.test == BAN_EMAIL and ban.test_value(email):
+            elif ban.test == BAN_EMAIL and email and ban.test_value(email):
                 return ban
-            elif ip and ban.test == BAN_IP and ban.test_value(ip):
+            elif ban.test == BAN_IP and ip and ban.test_value(ip):
                 return ban
-        return False
+        return None
 
 
 class Ban(models.Model):
-    test = models.PositiveIntegerField(default=BAN_NAME, db_index=True)
+    test = models.PositiveIntegerField(default=BAN_USERNAME, db_index=True)
     banned_value = models.CharField(max_length=255, db_index=True)
     user_message = models.TextField(null=True, blank=True)
     staff_message = models.TextField(null=True, blank=True)
     valid_until = models.DateField(null=True, blank=True, db_index=True)
-    is_valid = models.BooleanField(default=False, db_index=True)
+    is_valid = models.BooleanField(default=True, db_index=True)
 
     objects = BansManager()
 
@@ -360,7 +361,7 @@ class Ban(models.Model):
     def test_value(self, value):
         if '*' in self.banned_value:
             regex = '^' + re.escape(self.banned_value).replace('\*', '(.*?)') + '$'
-            return re.search(regex, value)
+            return re.search(regex, value) != None
         else:
             return self.banned_value == value
 

+ 65 - 0
misago/users/tests/test_ban_model.py

@@ -0,0 +1,65 @@
+#-*- coding: utf-8 -*-
+from django.test import TestCase
+from misago.users.models import Ban, BAN_USERNAME, BAN_EMAIL, BAN_IP
+
+
+class BansManagerTests(TestCase):
+    def setUp(self):
+        Ban.objects.bulk_create([
+            Ban(test=BAN_USERNAME, banned_value='bob'),
+            Ban(test=BAN_EMAIL, banned_value='bob@test.com'),
+            Ban(test=BAN_IP, banned_value='127.0.0.1'),
+        ])
+
+    def test_find_ban_for_banned_name(self):
+        """find_ban finds ban for given username"""
+        self.assertTrue(Ban.objects.find_ban(username='Bob') != None)
+        self.assertTrue(Ban.objects.find_ban(username='Jeb') == None)
+
+    def test_find_ban_for_banned_email(self):
+        """find_ban finds ban for given email"""
+        self.assertTrue(Ban.objects.find_ban(email='bob@test.com') != None)
+        self.assertTrue(Ban.objects.find_ban(email='jeb@test.com') == None)
+
+    def test_find_ban_for_banned_ip(self):
+        """find_ban finds ban for given ip"""
+        self.assertTrue(Ban.objects.find_ban(ip='127.0.0.1') != None)
+        self.assertTrue(Ban.objects.find_ban(ip='42.0.0.1') == None)
+
+    def test_find_ban_for_all_bans(self):
+        """find_ban finds ban for given values"""
+        valid_kwargs = {'username': 'bob', 'ip': '42.51.52.51'}
+        self.assertTrue(Ban.objects.find_ban(**valid_kwargs) != None)
+
+        invalid_kwargs = {'username': 'bsob', 'ip': '42.51.52.51'}
+        self.assertTrue(Ban.objects.find_ban(**invalid_kwargs) == None)
+
+
+class BanTests(TestCase):
+    def test_test_value_literal(self):
+        """ban correctly tests given values"""
+        test_ban = Ban(banned_value='bob')
+
+        self.assertTrue(test_ban.test_value('bob'))
+        self.assertFalse(test_ban.test_value('bobby'))
+
+    def test_test_value_starts_with(self):
+        """ban correctly tests given values"""
+        test_ban = Ban(banned_value='bob*')
+
+        self.assertTrue(test_ban.test_value('bob'))
+        self.assertTrue(test_ban.test_value('bobby'))
+
+    def test_test_value_middle_match(self):
+        """ban correctly tests given values"""
+        test_ban = Ban(banned_value='b*b')
+
+        self.assertTrue(test_ban.test_value('bob'))
+        self.assertTrue(test_ban.test_value('bobby'))
+
+    def test_test_value_middle_match(self):
+        """ban correctly tests given values"""
+        test_ban = Ban(banned_value='*bob')
+
+        self.assertTrue(test_ban.test_value('lebob'))
+        self.assertFalse(test_ban.test_value('bobby'))

+ 95 - 0
misago/users/tests/test_banadmin_views.py

@@ -0,0 +1,95 @@
+from datetime import date
+from django.core.urlresolvers import reverse
+from misago.admin.testutils import AdminTestCase
+from misago.users.models import Ban
+
+
+class BanAdminViewsTests(AdminTestCase):
+    def test_link_registered(self):
+        """admin nav contains bans link"""
+        response = self.client.get(
+            reverse('misago:admin:users:accounts:index'))
+
+        response = self.client.get(response['location'])
+        self.assertIn(reverse('misago:admin:users:bans:index'),
+                      response.content)
+
+    def test_list_view(self):
+        """bans list view returns 200"""
+        response = self.client.get(reverse('misago:admin:users:bans:index'))
+        self.assertEqual(response.status_code, 302)
+
+        response = self.client.get(response['location'])
+        self.assertEqual(response.status_code, 200)
+
+    def test_new_view(self):
+        """new ban view has no showstoppers"""
+        response = self.client.get(
+            reverse('misago:admin:users:bans:new'))
+        self.assertEqual(response.status_code, 200)
+
+        response = self.client.post(
+            reverse('misago:admin:users:bans:new'),
+            data={
+                'test': '1',
+                'banned_value': 'test@test.com',
+                'user_message': 'Lorem ipsum dolor met',
+                'staff_message': 'Sit amet elit',
+                'valid_until': '12-24-%s' % unicode(date.today().year + 1),
+            })
+        self.assertEqual(response.status_code, 302)
+
+        response = self.client.get(reverse('misago:admin:users:bans:index'))
+        response = self.client.get(response['location'])
+        self.assertEqual(response.status_code, 200)
+        self.assertIn('test@test.com', response.content)
+
+    def test_edit_view(self):
+        """edit ban view has no showstoppers"""
+        self.client.post(
+            reverse('misago:admin:users:bans:new'),
+            data={
+                'test': '0',
+                'banned_value': 'Admin',
+            })
+
+        test_ban = Ban.objects.get(banned_value='admin')
+        response = self.client.post(
+            reverse('misago:admin:users:bans:edit',
+                    kwargs={'ban_id': test_ban.pk}),
+            data={
+                'test': '1',
+                'banned_value': 'test@test.com',
+                'user_message': 'Lorem ipsum dolor met',
+                'staff_message': 'Sit amet elit',
+                'valid_until': '12-24-%s' % unicode(date.today().year + 1),
+            })
+        self.assertEqual(response.status_code, 302)
+
+        response = self.client.get(reverse('misago:admin:users:bans:index'))
+        response = self.client.get(response['location'])
+        self.assertEqual(response.status_code, 200)
+        self.assertIn('test@test.com', response.content)
+
+    def test_delete_view(self):
+        """delete ban view has no showstoppers"""
+        self.client.post(
+            reverse('misago:admin:users:bans:new'),
+            data={
+                'test': '0',
+                'banned_value': 'TestBan',
+            })
+
+        test_ban = Ban.objects.get(banned_value='testban')
+
+        response = self.client.post(
+            reverse('misago:admin:users:bans:delete',
+                    kwargs={'ban_id': test_ban.pk}))
+        self.assertEqual(response.status_code, 302)
+
+        response = self.client.get(reverse('misago:admin:users:bans:index'))
+        self.client.get(response['location'])
+        response = self.client.get(response['location'])
+
+        self.assertEqual(response.status_code, 200)
+        self.assertTrue(test_ban.banned_value not in response.content)

+ 35 - 1
misago/users/tests/test_validators.py

@@ -3,10 +3,14 @@ from django.contrib.auth import get_user_model
 from django.core.exceptions import ValidationError
 from django.test import TestCase
 from misago.conf import settings
-from misago.users.validators import (validate_email, validate_email_available,
+from misago.users.models import Ban, BAN_USERNAME, BAN_EMAIL
+from misago.users.validators import (validate_email,
+                                     validate_email_available,
+                                     validate_email_banned,
                                      validate_password,
                                      validate_username,
                                      validate_username_available,
+                                     validate_username_banned,
                                      validate_username_content,
                                      validate_username_length)
 
@@ -21,6 +25,7 @@ class ValidateEmailAvailableTests(TestCase):
     def test_valid_email(self):
         """validate_email_available allows available emails"""
         validate_email_available('bob@boberson.com')
+        validate_email_available(self.test_user.email, exclude=self.test_user)
 
     def test_invalid_email(self):
         """validate_email_available disallows unvailable emails"""
@@ -28,6 +33,19 @@ class ValidateEmailAvailableTests(TestCase):
             validate_email_available(self.test_user.email)
 
 
+class ValidateEmailBannedTests(TestCase):
+    def setUp(self):
+        Ban.objects.create(test=BAN_EMAIL, banned_value="ban@test.com")
+
+    def test_unbanned_name(self):
+        """unbanned email passes validation"""
+        validate_email_banned('noban@test.com')
+
+    def test_banned_name(self):
+        """banned email fails validation"""
+        with self.assertRaises(ValidationError):
+            validate_email_banned('ban@test.com')
+
 class ValidateEmailTests(TestCase):
     def test_validate_email(self):
         """validate_email has no crashes"""
@@ -65,6 +83,8 @@ class ValidateUsernameAvailableTests(TestCase):
     def test_valid_name(self):
         """validate_username_available allows available names"""
         validate_username_available('BobBoberson')
+        validate_username_available(self.test_user.username,
+                                    exclude=self.test_user)
 
     def test_invalid_name(self):
         """validate_username_available disallows unvailable names"""
@@ -72,6 +92,20 @@ class ValidateUsernameAvailableTests(TestCase):
             validate_username_available(self.test_user.username)
 
 
+class ValidateUsernameBannedTests(TestCase):
+    def setUp(self):
+        Ban.objects.create(test=BAN_USERNAME, banned_value="Bob")
+
+    def test_unbanned_name(self):
+        """unbanned name passes validation"""
+        validate_username_banned('Luke')
+
+    def test_banned_name(self):
+        """banned name fails validation"""
+        with self.assertRaises(ValidationError):
+            validate_username_banned('Bob')
+
+
 class ValidateUsernameContentTests(TestCase):
     def test_valid_name(self):
         """validate_username_content allows valid names"""

+ 6 - 1
misago/users/views/bansadmin.py → misago/users/views/banadmin.py

@@ -25,7 +25,12 @@ class BanAdmin(generic.AdminBaseMixin):
 
 class BansList(BanAdmin, generic.ListView):
     items_per_page = 30
-    ordering = (('-id', None),)
+    ordering = (
+        ('-id', _("From newest")),
+        ('id', _("From oldest")),
+        ('banned_value', _("A to z")),
+        ('-banned_value', _("Z to a")),
+    )
     SearchForm = SearchBansForm
     selection_label = _('With bans: 0')
     empty_selection_label = _('Select bans')