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

feat: adds sorting support to enterprise-customer-members endpoint #2311

Merged
merged 3 commits into from
Jan 13, 2025
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
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ Unreleased
----------
* nothing unreleased

[5.6.0]
--------
* feat: Adds sorting support to enterprise-customer-members endpoint

[5.5.2]
--------
* feat: Add page_size support to enterprise-customer-members endpoint
Expand Down
2 changes: 1 addition & 1 deletion enterprise/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
Your project description goes here.
"""

__version__ = "5.5.2"
__version__ = "5.6.0"
18 changes: 17 additions & 1 deletion enterprise/api/v1/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1922,7 +1922,22 @@ def get_role_assignments(self, obj):
return None


class EnterpriseMembersSerializer(serializers.Serializer):
class EnterpriseCustomerMembersRequestQuerySerializer(serializers.Serializer):
"""
Serializer for the Enterprise Customer Members endpoint query filter
"""
user_query = serializers.CharField(required=False, max_length=250)
sort_by = serializers.ChoiceField(
choices=[
('name', 'name'),
('joined_org', 'joined_org'),
],
required=False,
)
is_reversed = serializers.BooleanField(required=False, default=False)


class EnterpriseMembersSerializer(serializers.ModelSerializer):
"""
Serializer for EnterpriseCustomerUser model with additions.
"""
Expand Down Expand Up @@ -1954,6 +1969,7 @@ def get_enterprise_customer_user(self, obj):
"""
if user := obj:
return {
"user_id": user[0],
"email": user[1],
"joined_org": user[2].strftime("%b %d, %Y"),
"name": user[3],
Expand Down
31 changes: 29 additions & 2 deletions enterprise/api/v1/views/enterprise_customer_members.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from rest_framework import permissions, response, status
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response

from django.core.exceptions import ValidationError
from django.db import connection
Expand Down Expand Up @@ -63,13 +64,31 @@
def get_members(self, request, *args, **kwargs):
"""
Get all members associated with that enterprise customer

Request Arguments:
- ``enterprise_uuid`` (URL location, required): The uuid of the enterprise from which learners should be listed.

Optional query params:
- ``user_query`` (string, optional): Filter the returned members by user name and email with a provided
sub-string
- ``sort_by`` (string, optional): Specify how the returned members should be ordered. Supported sorting values
are `joined_org`, `name`, and `enrollments`.
- ``is_reversed`` (bool, optional): Include to reverse the records in descending order. By default, the results
returned are in ascending order.
"""
query_params = self.request.query_params
param_serializers = serializers.EnterpriseCustomerMembersRequestQuerySerializer(

Check warning on line 80 in enterprise/api/v1/views/enterprise_customer_members.py

View check run for this annotation

Codecov / codecov/patch

enterprise/api/v1/views/enterprise_customer_members.py#L79-L80

Added lines #L79 - L80 were not covered by tests
data=query_params
)
if not param_serializers.is_valid():
return Response(param_serializers.errors, status=400)

Check warning on line 84 in enterprise/api/v1/views/enterprise_customer_members.py

View check run for this annotation

Codecov / codecov/patch

enterprise/api/v1/views/enterprise_customer_members.py#L84

Added line #L84 was not covered by tests
enterprise_uuid = kwargs.get("enterprise_uuid", None)
# Raw sql is picky about uuid format
uuid_no_dashes = str(enterprise_uuid).replace("-", "")
users = []
user_query = self.request.query_params.get("user_query", None)

user_query = param_serializers.validated_data.get('user_query')
is_reversed = param_serializers.validated_data.get('is_reversed', False)
sort_by = param_serializers.validated_data.get('sort_by')

Check warning on line 91 in enterprise/api/v1/views/enterprise_customer_members.py

View check run for this annotation

Codecov / codecov/patch

enterprise/api/v1/views/enterprise_customer_members.py#L89-L91

Added lines #L89 - L91 were not covered by tests
# On logistration, the name field of auth_userprofile is populated, but if it's not
# filled in, we check the auth_user model for it's first/last name fields
# https://2u-internal.atlassian.net/wiki/spaces/ENGAGE/pages/747143186/Use+of+full+name+in+edX#Data-on-Name-Field
Expand Down Expand Up @@ -109,6 +128,14 @@
status=status.HTTP_404_NOT_FOUND,
)

if sort_by:
lambda_keys = {

Check warning on line 132 in enterprise/api/v1/views/enterprise_customer_members.py

View check run for this annotation

Codecov / codecov/patch

enterprise/api/v1/views/enterprise_customer_members.py#L132

Added line #L132 was not covered by tests
# 3 and 2 are indices in the tuple associated to a user row (uuid, email, joined_org, name)
'name': lambda t: t[3],
'joined_org': lambda t: t[2],
}
users = sorted(users, key=lambda_keys.get(sort_by), reverse=is_reversed)

Check warning on line 137 in enterprise/api/v1/views/enterprise_customer_members.py

View check run for this annotation

Codecov / codecov/patch

enterprise/api/v1/views/enterprise_customer_members.py#L137

Added line #L137 was not covered by tests

# paginate the queryset
users_page = self.paginator.paginate_queryset(users, request, view=self)

Expand Down
2 changes: 2 additions & 0 deletions tests/test_enterprise/api/test_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,7 @@ def setUp(self):
def test_serialize_users(self):
expected_user = {
'enterprise_customer_user': {
'user_id': self.user_1.id,
'email': self.user_1.email,
'joined_org': self.user_1.date_joined.strftime("%b %d, %Y"),
'name': (self.user_1.first_name + ' ' + self.user_1.last_name),
Expand All @@ -609,6 +610,7 @@ def test_serialize_users(self):

expected_user_2 = {
'enterprise_customer_user': {
'user_id': self.user_2.id,
'email': self.user_2.email,
'joined_org': self.user_2.date_joined.strftime("%b %d, %Y"),
'name': self.user_2.first_name + ' ' + self.user_2.last_name,
Expand Down
Loading