diff --git a/openlobby/core/api/schema.py b/openlobby/core/api/schema.py index cc99dac02427a68f12e8ec93a5492be90e34cf09..9060e6ca465f24f7a8757dd0247cac4707374a2f 100644 --- a/openlobby/core/api/schema.py +++ b/openlobby/core/api/schema.py @@ -1,12 +1,12 @@ import graphene -from graphene import relay from django.db.models import Count, Q +from graphene import relay from . import types -from ..models import OpenIdClient from .paginator import Paginator from .sanitizers import extract_text from .. import search +from ..models import OpenIdClient from ..models import User, Report AUTHOR_SORT_LAST_NAME_ID = 1 @@ -73,9 +73,7 @@ class Query: authors = User.objects\ .sorted(**kwargs)\ - .filter(is_author=True)\ - .annotate(total_reports=Count('report', filter=Q(report__is_draft=False)))[ - paginator.slice_from:paginator.slice_to] + .filter(is_author=True)[paginator.slice_from:paginator.slice_to] page_info = paginator.get_page_info(total) diff --git a/openlobby/core/models.py b/openlobby/core/models.py index 7a4ccb87c711f604b31d181e5554d6dfc7467861..8c46ec0e6455123c6318a998e037bd34e0888686 100644 --- a/openlobby/core/models.py +++ b/openlobby/core/models.py @@ -1,17 +1,20 @@ +import time + from django.conf import settings from django.contrib.auth.base_user import BaseUserManager -from django.db import models from django.contrib.auth.models import AbstractUser from django.contrib.postgres.fields import JSONField +from django.db import models +from django.db.models import Count +from django.db.models import Q from django.utils import timezone -import time -class UserManager(BaseUserManager): +class UserManager(BaseUserManager): def sorted(self, **kwargs): # inline import intentionally from openlobby.core.api.schema import AUTHOR_SORT_LAST_NAME_ID, AUTHOR_SORT_TOTAL_REPORTS_ID - qs = self.get_queryset() + qs = self.get_queryset().annotate(total_reports=Count('report', filter=Q(report__is_draft=False))) sort_field = kwargs.get('sort', AUTHOR_SORT_LAST_NAME_ID) if sort_field == AUTHOR_SORT_LAST_NAME_ID: return qs.order_by('{}last_name'.format('-' if kwargs.get('reversed', False) else ''), 'first_name') @@ -34,7 +37,7 @@ class User(AbstractUser): # deal with first name and last name collisions if self.is_author: collisions = User.objects.filter(first_name=self.first_name, last_name=self.last_name, - is_author=True).exclude(id=self.id) + is_author=True).exclude(id=self.id) if collisions.count() > 0: self.has_colliding_name = True collisions.update(has_colliding_name=True) diff --git a/tests/test_models.py b/tests/test_models.py index 2cc7a8c4c64d063d0824ad4bbb8df4b73ed9081d..80e382a634e2b929e4c7a7ec5912bd2d1cee682d 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,11 +1,11 @@ -import pytest -import arrow -from django.conf import settings from unittest.mock import patch -from openlobby.core.models import Report, User, OpenIdClient, LoginAttempt +import arrow +import pytest +from django.conf import settings +from openlobby.core.api.schema import AUTHOR_SORT_LAST_NAME_ID, AUTHOR_SORT_TOTAL_REPORTS_ID from openlobby.core.documents import ReportDoc - +from openlobby.core.models import Report, User, OpenIdClient, LoginAttempt pytestmark = [pytest.mark.django_db, pytest.mark.usefixtures('django_es')] @@ -82,7 +82,7 @@ def test_login_attempt__default_expiration(): client = OpenIdClient.objects.create(name='a', client_id='b', client_secret='c') with patch('openlobby.core.models.time.time', return_value=10000): attempt = LoginAttempt.objects.create(openid_client=client, state='foo', - app_redirect_uri='http://openlobby/app') + app_redirect_uri='http://openlobby/app') assert attempt.expiration == 10000 + settings.LOGIN_ATTEMPT_EXPIRATION @@ -118,3 +118,42 @@ def test_user__name_collision_excludes_self_on_update(): u = User.objects.create(username='a', is_author=True, first_name='Ryan', last_name='Gosling') u.save() assert User.objects.get(username='a').has_colliding_name is False + + +def test_user__sorted_default(): + User.objects.create(username='a', is_author=False, first_name='Ryan', last_name='AGosling') + User.objects.create(username='b', is_author=True, first_name='Ryan', last_name='BGosling') + User.objects.create(username='c', is_author=False, first_name='Ryan', last_name='CGosling') + assert User.objects.sorted()[0].username == 'a' + + +def test_user__sorted_default_reversed(): + User.objects.create(username='a', is_author=False, first_name='Ryan', last_name='AGosling') + User.objects.create(username='b', is_author=True, first_name='Ryan', last_name='BGosling') + User.objects.create(username='c', is_author=False, first_name='Ryan', last_name='CGosling') + assert User.objects.sorted(reversed=True)[0].username == 'c' + + +def test_user__sorted_last_name(): + User.objects.create(username='a', is_author=False, first_name='Ryan', last_name='AGosling') + User.objects.create(username='b', is_author=True, first_name='Ryan', last_name='BGosling') + User.objects.create(username='c', is_author=False, first_name='Ryan', last_name='CGosling') + assert User.objects.sorted(sort=AUTHOR_SORT_LAST_NAME_ID)[0].username == 'a' + assert User.objects.sorted(sort=AUTHOR_SORT_LAST_NAME_ID, reversed=False)[0].username == 'a' + assert User.objects.sorted(sort=AUTHOR_SORT_LAST_NAME_ID, reversed=True)[0].username == 'c' + + +def test_user__sorted_total_reports(): + author = User.objects.create(username='a', is_author=True, first_name='Ryan', last_name='AGosling') + User.objects.create(username='b', is_author=True, first_name='Ryan', last_name='BGosling') + date = arrow.get(2018, 1, 1).datetime + Report.objects.create( + id=7, + author=author, + date=date, + published=date, + body='Lorem ipsum.', + ) + assert User.objects.sorted(sort=AUTHOR_SORT_TOTAL_REPORTS_ID)[0].username == 'a' + assert User.objects.sorted(sort=AUTHOR_SORT_TOTAL_REPORTS_ID, reversed=False)[0].username == 'a' + assert User.objects.sorted(sort=AUTHOR_SORT_TOTAL_REPORTS_ID, reversed=True)[0].username == 'b'