Skip to content

Commit 7638992

Browse files
committed
squash!: Fix search and add tests
1 parent f669569 commit 7638992

2 files changed

Lines changed: 406 additions & 9 deletions

File tree

openedx_authz/rest_api/v1/views.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -650,39 +650,43 @@ class AdminConsoleScopesAPIView(generics.ListAPIView):
650650

651651
serializer_class = ScopeSerializer
652652
pagination_class = AuthZAPIViewPagination
653-
filter_backends = [filters.SearchFilter]
654-
search_fields = ["display_name"]
655653
permission_classes = [AnyScopePermission]
656654

657655
def get_serializer_context(self):
658656
context = super().get_serializer_context()
659657
context["org_map"] = {org.short_name: org for org in Organization.objects.all()}
660658
return context
661659

662-
def _get_courses_queryset(self, allowed_ids: set | None = None) -> QuerySet:
660+
def _get_courses_queryset(self, allowed_ids: set | None = None, search: str = "") -> QuerySet:
663661
"""Return a CourseOverview queryset projected to the unified scope shape.
664662
665663
If allowed_ids is provided, filter to only those course keys.
664+
If search is provided, filter by display_name.
666665
"""
667666
qs = CourseOverview.objects
668667
if allowed_ids is not None:
669668
qs = qs.filter(id__in=allowed_ids)
669+
if search:
670+
qs = qs.filter(display_name__icontains=search)
670671
return qs.annotate(
671672
scope_id=Cast("id", output_field=CharField()),
672673
org_name=Cast("org", output_field=CharField()),
673674
scope_type=Value("course", output_field=CharField()),
674675
).values("scope_id", "display_name", "org_name", "scope_type")
675676

676-
def _get_libraries_queryset(self, allowed_pairs: set | None = None) -> QuerySet:
677+
def _get_libraries_queryset(self, allowed_pairs: set | None = None, search: str = "") -> QuerySet:
677678
"""Return a ContentLibrary queryset projected to the unified scope shape.
678679
679680
If allowed_pairs is provided, filter to only those (org, slug) pairs.
681+
If search is provided, filter by learning_package__title.
680682
"""
681683
qs = ContentLibrary.objects
682684
if allowed_pairs is not None:
683685
qs = qs.filter(
684686
reduce(operator.or_, (Q(org__short_name=org, slug=slug) for org, slug in allowed_pairs), Q())
685687
)
688+
if search:
689+
qs = qs.filter(learning_package__title__icontains=search)
686690
return qs.annotate(
687691
scope_id=Cast("slug", output_field=CharField()),
688692
org_name=Cast("org__short_name", output_field=CharField()),
@@ -693,7 +697,8 @@ def _build_queryset(self, courses_qs: QuerySet | None, libraries_qs: QuerySet |
693697
"""Union the provided querysets and sort by org. If only one is provided, return it sorted directly."""
694698
if courses_qs is not None and libraries_qs is not None:
695699
return courses_qs.union(libraries_qs).order_by("org_name")
696-
return (courses_qs or libraries_qs).order_by("org_name")
700+
qs = courses_qs if courses_qs is not None else libraries_qs
701+
return qs.order_by("org_name")
697702

698703
def get_queryset(self) -> QuerySet:
699704
"""Return scopes ordered by org, filtered by the user's permissions."""
@@ -703,12 +708,13 @@ def get_queryset(self) -> QuerySet:
703708
params_serializer = ListScopesSerializer(data=self.request.query_params)
704709
params_serializer.is_valid(raise_exception=True)
705710
scope_type = params_serializer.validated_data["type"]
711+
search = self.request.query_params.get("search", "").strip()
706712

707713
# Staff and superusers can see all scopes, skip permission filtering.
708714
if user.is_staff or user.is_superuser:
709715
return self._build_queryset(
710-
courses_qs=self._get_courses_queryset() if scope_type != "library" else None,
711-
libraries_qs=self._get_libraries_queryset() if scope_type != "course" else None,
716+
courses_qs=self._get_courses_queryset(search=search) if scope_type != "library" else None,
717+
libraries_qs=self._get_libraries_queryset(search=search) if scope_type != "course" else None,
712718
)
713719

714720
management_only = params_serializer.validated_data["management_permission_only"]
@@ -726,7 +732,7 @@ def get_permission(scope_cls):
726732
user.username, get_permission(CourseOverviewData).identifier
727733
)
728734
}
729-
courses_qs = self._get_courses_queryset(allowed_course_ids)
735+
courses_qs = self._get_courses_queryset(allowed_course_ids, search=search)
730736

731737
libraries_qs = None
732738
if scope_type != "course":
@@ -737,7 +743,7 @@ def get_permission(scope_cls):
737743
user.username, get_permission(ContentLibraryData).identifier
738744
)
739745
}
740-
libraries_qs = self._get_libraries_queryset(allowed_library_pairs)
746+
libraries_qs = self._get_libraries_queryset(allowed_library_pairs, search=search)
741747

742748
# Union the requested querysets and sort by org at the DB level.
743749
return self._build_queryset(courses_qs, libraries_qs)

0 commit comments

Comments
 (0)