Browse Source

Fix py3k build, settle on changes to user namechange availability util

Rafał Pitoń 7 years ago
parent
commit
6eed1f29a4

+ 2 - 2
misago/threads/tests/test_thread_merge_api.py

@@ -67,7 +67,7 @@ class ThreadMergeApiTests(ThreadsApiTestCase):
         self.override_acl({'can_merge_threads': 0})
 
         response = self.client.post(self.api_link)
-        self.assertEqual(response.status_code, 400)
+        self.assertEqual(response.status_code, 403)
         self.assertEqual(response.json(), {
             'detail': "You can't merge threads in this category.",
         })
@@ -127,7 +127,7 @@ class ThreadMergeApiTests(ThreadsApiTestCase):
         self.assertEqual(
             response.json(),
             {
-                'other_thread': )
+                'other_thread': [
                     "The thread you have entered link to doesn't exist or "
                     "you don't have permission to see it."
                 ],

+ 17 - 27
misago/users/api/userendpoints/username.py

@@ -4,7 +4,7 @@ from django.db import IntegrityError
 from django.utils.translation import ugettext as _
 
 from misago.conf import settings
-from misago.users.namechanges import UsernameChanges
+from misago.users.namechanges import get_available_namechanges_data
 from misago.users.serializers import ChangeUsernameSerializer
 
 
@@ -12,36 +12,22 @@ def username_endpoint(request):
     if request.method == 'POST':
         return change_username(request)
     else:
-        return options_response(get_username_options(request.user))
-
-
-def get_username_options(user):
-    options = UsernameChanges(user)
-    return {
-        'changes_left': options.left,
-        'next_change_on': options.next_change_on,
-        'length_min': settings.username_length_min,
-        'length_max': settings.username_length_max,
-    }
-
-
-def options_response(options):
-    if options['next_change_on']:
-        options['next_change_on'] = options['next_change_on'].isoformat()
-    return Response(options)
+        form_options = get_available_namechanges_data(request.user)
+        form_options.update({
+            'length_min': settings.username_length_min,
+            'length_max': settings.username_length_max,
+        })
+        
+        return Response(form_options)
 
 
 def change_username(request):
-    options = get_username_options(request.user)
-    if not options['changes_left']:
-        if options['next_change_on']:
-            next_change_on = options['next_change_on'].isoformat()
-        else:
-            next_change_on = None
+    available_namechanges = get_available_namechanges_data(request.user)
+    if not available_namechanges['changes_left']:
         return Response(
             {
                 'username': [_("You can't change your username at this time.")],
-                'next_change_on': next_change_on,
+                'next_change_on': available_namechanges['next_change_on'],
             },
             status=400,
         )
@@ -56,11 +42,14 @@ def change_username(request):
 
     try:
         serializer.change_username(changed_by=request.user)
-        return Response({
+
+        response_data = get_available_namechanges_data(request.user)
+        response_data.update({
             'username': request.user.username,
             'slug': request.user.slug,
-            'options': get_username_options(request.user)
         })
+
+        return Response(response_data)
     except IntegrityError:
         return Response(
             {
@@ -91,6 +80,7 @@ def moderate_username_endpoint(request, profile):
                 status=400,
             )
     else:
+        # return form data
         return Response({
             'length_min': settings.username_length_min,
             'length_max': settings.username_length_max,

+ 1 - 1
misago/users/models/user.py

@@ -476,7 +476,7 @@ class UsernameChange(models.Model):
     old_username = models.CharField(max_length=255)
 
     class Meta:
-        get_latest_by = "changed_on"
+        get_latest_by = 'changed_on'
 
     def set_change_author(self, user):
         self.changed_by = user

+ 24 - 27
misago/users/namechanges.py

@@ -1,6 +1,3 @@
-"""
-Service for tracking namechanges
-"""
 from datetime import timedelta
 
 from django.utils import timezone
@@ -8,32 +5,32 @@ from django.utils import timezone
 from .models import UsernameChange
 
 
-class UsernameChanges(object):
-    def __init__(self, user):
-        self.left = 0
-        self.next_change_on = None
+def get_available_namechanges_data(user):
+    namechanges_data = {
+        'changes_left': 0,
+        'next_change_on': None,
+    }
 
-        if user.acl_cache['name_changes_allowed']:
-            self.count_namechanges(user)
+    if not user.acl_cache['name_changes_allowed']:
+        return namechanges_data
 
-    def count_namechanges(self, user):
-        name_changes_allowed = user.acl_cache['name_changes_allowed']
-        name_changes_expire = user.acl_cache['name_changes_expire']
+    name_changes_allowed = user.acl_cache['name_changes_allowed']
+    name_changes_expire = user.acl_cache['name_changes_expire']
 
-        valid_changes_qs = user.namechanges.filter(changed_by=user)
-        if name_changes_expire:
-            cutoff = timezone.now() - timedelta(days=name_changes_expire)
-            valid_changes_qs = valid_changes_qs.filter(changed_on__gte=cutoff)
+    valid_changes_qs = user.namechanges.filter(changed_by=user)
+    if name_changes_expire:
+        cutoff = timezone.now() - timedelta(days=name_changes_expire)
+        valid_changes_qs = valid_changes_qs.filter(changed_on__gte=cutoff)
 
-        used_changes = valid_changes_qs.count()
-        if name_changes_allowed <= used_changes:
-            self.left = 0
-        else:
-            self.left = name_changes_allowed - used_changes
+    used_changes = valid_changes_qs.count()
+    if name_changes_allowed > used_changes:
+        namechanges_data['changes_left'] = name_changes_allowed - used_changes
 
-        if not self.left and name_changes_expire:
-            try:
-                self.next_change_on = valid_changes_qs.latest().changed_on
-                self.next_change_on += timedelta(days=name_changes_expire)
-            except UsernameChange.DoesNotExist:
-                pass
+    if not namechanges_data['changes_left'] and name_changes_expire:
+        try:
+            namechanges_data['next_change_on'] = valid_changes_qs.latest().changed_on
+            namechanges_data['next_change_on'] += timedelta(days=name_changes_expire)
+        except UsernameChange.DoesNotExist:
+            pass
+    
+    return namechanges_data

+ 11 - 7
misago/users/tests/test_namechanges.py

@@ -1,7 +1,7 @@
 from django.contrib.auth import get_user_model
 from django.test import TestCase
 
-from misago.users.namechanges import UsernameChanges
+from misago.users.namechanges import get_available_namechanges_data
 
 
 UserModel = get_user_model()
@@ -12,17 +12,21 @@ class UsernameChangesTests(TestCase):
         """username changes are tracked correctly"""
         test_user = UserModel.objects.create_user('Bob', 'bob@bob.com', 'pass123')
 
-        namechanges = UsernameChanges(test_user)
-        self.assertEqual(namechanges.left, 2)
-        self.assertIsNone(namechanges.next_on)
+        namechanges = get_available_namechanges_data(test_user)
+        self.assertEqual(namechanges, {
+            'changes_left': 2,
+            'next_change_on': None,
+        })
 
         self.assertEqual(test_user.namechanges.count(), 0)
 
         test_user.set_username('Boberson')
         test_user.save(update_fields=['username', 'slug'])
 
-        namechanges = UsernameChanges(test_user)
-        self.assertEqual(namechanges.left, 1)
-        self.assertIsNone(namechanges.next_on)
+        namechanges = get_available_namechanges_data(test_user)
+        self.assertEqual(namechanges, {
+            'changes_left': 1,
+            'next_change_on': None,
+        })
 
         self.assertEqual(test_user.namechanges.count(), 1)

+ 4 - 9
misago/users/tests/test_user_username_api.py

@@ -17,9 +17,8 @@ class UserUsernameTests(AuthenticatedUserTestCase):
         super(UserUsernameTests, self).setUp()
         self.link = '/api/users/%s/username/' % self.user.pk
 
-    def test_get_change_username_options(self):
-        """get to API returns options"""
-
+    def test_get_change_username_form_options(self):
+        """get to API returns form options"""
         response = self.client.get(self.link)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.json(), {
@@ -108,12 +107,8 @@ class UserUsernameTests(AuthenticatedUserTestCase):
         self.assertEqual(response.json(), {
             'username': 'NewUsernamu',
             'slug': 'newusernamu',
-            'options': {
-                'changes_left': 1,
-                'next_change_on': None,
-                'length_min': settings.username_length_min,
-                'length_max': settings.username_length_max,
-            },
+            'changes_left': 1,
+            'next_change_on': None,
         })
 
         self.reload_user()