Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ordering for FacilityUser viewset #12324

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions kolibri/core/auth/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
from kolibri.core import error_constants
from kolibri.core.api import ReadOnlyValuesViewset
from kolibri.core.api import ValuesViewset
from kolibri.core.api import ValuesViewsetOrderingFilter
from kolibri.core.auth.constants.demographics import NOT_SPECIFIED
from kolibri.core.auth.permissions.general import _user_is_admin_for_own_facility
from kolibri.core.auth.permissions.general import DenyAll
Expand All @@ -90,7 +91,6 @@
from kolibri.core.utils.pagination import ValuesViewsetPageNumberPagination
from kolibri.plugins.app.utils import interface


logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -394,6 +394,7 @@ class FacilityUserViewSet(ValuesViewset):
KolibriAuthPermissionsFilter,
DjangoFilterBackend,
filters.SearchFilter,
ValuesViewsetOrderingFilter,
)
order_by_field = "username"

Expand All @@ -415,6 +416,16 @@ class FacilityUserViewSet(ValuesViewset):
"gender",
"birth_year",
"extra_demographics",
"date_joined",
)

ordering_fields = (
"id",
"username",
"full_name",
"gender",
"birth_year",
"date_joined",
)

field_map = {
Expand All @@ -424,6 +435,8 @@ class FacilityUserViewSet(ValuesViewset):
def consolidate(self, items, queryset):
output = []
items = sorted(items, key=lambda x: x["id"])
ordering_param = self.request.query_params.get("ordering", self.order_by_field)
reverse = False
for key, group in groupby(items, lambda x: x["id"]):
roles = []
for item in group:
Expand All @@ -438,7 +451,11 @@ def consolidate(self, items, queryset):
roles.append(role)
item["roles"] = roles
output.append(item)
output = sorted(output, key=lambda x: x[self.order_by_field])
if ordering_param.startswith("-"):
ordering_param = ordering_param[1:]
reverse = True

output = sorted(output, key=lambda x: x[ordering_param], reverse=reverse)
return output

def perform_update(self, serializer):
Expand Down
101 changes: 101 additions & 0 deletions kolibri/core/auth/test/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import time
import uuid
from datetime import datetime
from datetime import timedelta
from importlib import import_module

import factory
Expand Down Expand Up @@ -1083,6 +1084,7 @@ def test_user_list(self):
"id_number": self.user.id_number,
"gender": self.user.gender,
"birth_year": self.user.birth_year,
"date_joined": self.user.date_joined,
"is_superuser": False,
"roles": [],
"extra_demographics": None,
Expand All @@ -1094,6 +1096,7 @@ def test_user_list(self):
"facility": self.superuser.facility_id,
"id_number": self.superuser.id_number,
"gender": self.superuser.gender,
"date_joined": self.superuser.date_joined,
"birth_year": self.superuser.birth_year,
"is_superuser": True,
"roles": [
Expand Down Expand Up @@ -1127,6 +1130,7 @@ def test_user_list_self(self):
"id_number": self.user.id_number,
"gender": self.user.gender,
"birth_year": self.user.birth_year,
"date_joined": self.user.date_joined,
"is_superuser": False,
"roles": [],
"extra_demographics": None,
Expand Down Expand Up @@ -1170,6 +1174,103 @@ def test_anonymous_no_retrieve_user(self):
self.assertEqual(response.status_code, 404)


class FacilityUserOrderingTestCase(APITestCase):
@classmethod
def setUpTestData(cls):
provision_device()
cls.facility = FacilityFactory.create()
cls.superuser = create_superuser(cls.facility)
cls.facility.add_admin(cls.superuser)

base_time = datetime.now() - timedelta(days=3)
cls.user1 = FacilityUserFactory.create(
facility=cls.facility, username="mario", date_joined=base_time
)
cls.user2 = FacilityUserFactory.create(
facility=cls.facility,
username="luigi",
date_joined=base_time + timedelta(days=1),
)
cls.user3 = FacilityUserFactory.create(
facility=cls.facility,
username="batman",
date_joined=base_time + timedelta(days=4),
)

def setUp(self):
self.client.login(
username=self.superuser.username,
password=DUMMY_PASSWORD,
facility=self.facility,
)

def _sort_by_field(self, data, field, reverse=False):
return sorted(data, key=lambda x: x[field], reverse=reverse)

def test_default_ordering(self):
response = self.client.get(reverse("kolibri:core:facilityuser-list"))
self.assertEqual(response.status_code, 200)
data = response.data
self.assertEqual(data[0]["username"], "batman")
sorted_data = self._sort_by_field(data, "username")
self.assertEqual(data, sorted_data)

def test_ordering_by_username(self):
response = self.client.get(
reverse("kolibri:core:facilityuser-list") + "?ordering=username"
)
self.assertEqual(response.status_code, 200)
data = response.data
sorted_data = self._sort_by_field(data, "username")
self.assertEqual(data, sorted_data)

def test_ordering_by_username_desc(self):
response = self.client.get(
reverse("kolibri:core:facilityuser-list") + "?ordering=-username"
)
self.assertEqual(response.status_code, 200)
data = response.data
self.assertEqual(data[0]["username"], "superuser")
sorted_data = self._sort_by_field(data, "username", reverse=True)
self.assertEqual(data, sorted_data)

def test_ordering_by_date_joined(self):
response = self.client.get(
reverse("kolibri:core:facilityuser-list") + "?ordering=date_joined"
)
self.assertEqual(response.status_code, 200)
data = response.data
sorted_data = self._sort_by_field(data, "date_joined")
self.assertEqual(data, sorted_data)

def test_ordering_by_date_joined_desc(self):
response = self.client.get(
reverse("kolibri:core:facilityuser-list") + "?ordering=-date_joined"
)
self.assertEqual(response.status_code, 200)
data = response.data
sorted_data = self._sort_by_field(data, "date_joined", reverse=True)
self.assertEqual(data, sorted_data)

def test_ordering_by_full_name(self):
response = self.client.get(
reverse("kolibri:core:facilityuser-list") + "?ordering=full_name"
)
self.assertEqual(response.status_code, 200)
data = response.data
sorted_data = self._sort_by_field(data, "full_name")
self.assertEqual(data, sorted_data)

def test_ordering_by_full_name_desc(self):
response = self.client.get(
reverse("kolibri:core:facilityuser-list") + "?ordering=-full_name"
)
self.assertEqual(response.status_code, 200)
data = response.data
sorted_data = self._sort_by_field(data, "full_name", reverse=True)
self.assertEqual(data, sorted_data)


class FacilityUserFilterTestCase(APITestCase):
@classmethod
def setUpTestData(cls):
Expand Down
Loading