[FC-0059] feat: Add order query param to lib v2 API (#35005)

* feat: Add `order` query param to lib v2 API

* test: Add tests for lib v2 `order` field
This commit is contained in:
Yusuf Musleh
2024-07-02 17:51:00 +03:00
committed by GitHub
parent 2717e5c50e
commit c625a8d387
5 changed files with 55 additions and 2 deletions

View File

@@ -242,7 +242,7 @@ class LibraryXBlockType:
# ============
def get_libraries_for_user(user, org=None, library_type=None, text_search=None):
def get_libraries_for_user(user, org=None, library_type=None, text_search=None, order=None):
"""
Return content libraries that the user has permission to view.
"""
@@ -263,7 +263,22 @@ def get_libraries_for_user(user, org=None, library_type=None, text_search=None):
Q(learning_package__description__icontains=text_search)
)
return permissions.perms[permissions.CAN_VIEW_THIS_CONTENT_LIBRARY].filter(user, qs)
filtered = permissions.perms[permissions.CAN_VIEW_THIS_CONTENT_LIBRARY].filter(user, qs)
if order:
order_query = 'learning_package__'
valid_order_fields = ['title', 'created', 'updated']
# If order starts with a -, that means order descending (default is ascending)
if order.startswith('-'):
order_query = f"-{order_query}"
order = order[1:]
if order in valid_order_fields:
return filtered.order_by(f"{order_query}{order}")
else:
log.exception(f"Error ordering libraries by {order}: Invalid order field")
return filtered
def get_metadata(queryset, text_search=None):

View File

@@ -115,6 +115,7 @@ class BaseFilterSerializer(serializers.Serializer):
"""
text_search = serializers.CharField(default=None, required=False)
org = serializers.CharField(default=None, required=False)
order = serializers.CharField(default=None, required=False)
class ContentLibraryFilterSerializer(BaseFilterSerializer):

View File

@@ -89,6 +89,13 @@ class ContentLibrariesRestApiTest(APITransactionTestCase):
"""
assert big_dict.items() >= subset_dict.items()
def assertOrderEqual(self, libraries_list, expected_order):
"""
Assert that the provided list of libraries match the order of expected
list by comparing the slugs.
"""
assert [lib["slug"] for lib in libraries_list] == expected_order
# API helpers
def _api(self, method, url, data, expect_response):

View File

@@ -230,6 +230,27 @@ class ContentLibrariesTestCase(ContentLibrariesRestApiTest, OpenEdxEventsTestMix
'text_search': 'library-title-4'})) == 1
assert len(self._list_libraries({'type': VIDEO})) == 3
self.assertOrderEqual(
self._list_libraries({'order': 'title'}),
["test-lib-filter-1", "test-lib-filter-2", "l3", "l4", "l5"],
)
self.assertOrderEqual(
self._list_libraries({'order': '-title'}),
["l5", "l4", "l3", "test-lib-filter-2", "test-lib-filter-1"],
)
self.assertOrderEqual(
self._list_libraries({'order': 'created'}),
["test-lib-filter-1", "test-lib-filter-2", "l3", "l4", "l5"],
)
self.assertOrderEqual(
self._list_libraries({'order': '-created'}),
["l5", "l4", "l3", "test-lib-filter-2", "test-lib-filter-1"],
)
# An invalid order doesn't apply any specific ordering to the result, so just
# check if successfully returned libraries
assert len(self._list_libraries({'order': 'invalid'})) == 5
assert len(self._list_libraries({'order': '-invalid'})) == 5
# General Content Library XBlock tests:
def test_library_blocks(self):

View File

@@ -196,6 +196,13 @@ class LibraryRootView(GenericAPIView):
str,
description="The string used to filter libraries by searching in title, id, org, or description",
),
apidocs.query_parameter(
'order',
str,
description=(
"Name of the content library field to sort the results by. Prefix with a '-' to sort descending."
),
),
],
)
def get(self, request):
@@ -207,12 +214,14 @@ class LibraryRootView(GenericAPIView):
org = serializer.validated_data['org']
library_type = serializer.validated_data['type']
text_search = serializer.validated_data['text_search']
order = serializer.validated_data['order']
queryset = api.get_libraries_for_user(
request.user,
org=org,
library_type=library_type,
text_search=text_search,
order=order,
)
paginated_qs = self.paginate_queryset(queryset)
result = api.get_metadata(paginated_qs)