Skip to content

Commit a651a06

Browse files
committed
squash!: Apply suggestions and fixes
1 parent 5de2b7a commit a651a06

2 files changed

Lines changed: 36 additions & 3 deletions

File tree

openedx_authz/rest_api/v1/views.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,9 +690,10 @@ def _get_libraries_queryset(self, allowed_pairs: set | None = None, search: str
690690
qs = qs.filter(learning_package__title__icontains=search)
691691
return qs.annotate(
692692
scope_id=Cast("slug", output_field=CharField()),
693+
display_name=Cast("learning_package__title", output_field=CharField()),
693694
org_name=Cast("org__short_name", output_field=CharField()),
694695
scope_type=Value("library", output_field=CharField()),
695-
).values("scope_id", "learning_package__title", "org_name", "scope_type")
696+
).values("scope_id", "display_name", "org_name", "scope_type")
696697

697698
def _build_queryset(self, courses_qs: QuerySet | None, libraries_qs: QuerySet | None) -> QuerySet:
698699
"""Union the provided querysets and sort by org. If only one is provided, return it sorted directly."""

openedx_authz/tests/rest_api/test_views.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,8 @@ def setUp(self):
953953
self.addCleanup(self.build_qs_patcher.stop)
954954

955955
# The stub ContentLibrary uses 'title' directly instead of 'learning_package__title'.
956-
# Patch _get_libraries_queryset to use the stub-compatible field.
956+
# Patch _get_libraries_queryset to use the stub-compatible field, aliased as 'display_name'
957+
# to match the column name the union and serializer expect.
957958
def stub_get_libraries_queryset(_, allowed_pairs=None, search=""): # pylint: disable=unused-argument
958959
qs = ContentLibrary.objects
959960
if allowed_pairs is not None:
@@ -965,9 +966,10 @@ def stub_get_libraries_queryset(_, allowed_pairs=None, search=""): # pylint: di
965966
)
966967
return qs.annotate(
967968
scope_id=Cast("slug", output_field=CharField()),
969+
display_name=Cast("title", output_field=CharField()),
968970
org_name=Cast("org__short_name", output_field=CharField()),
969971
scope_type=Value("library", output_field=CharField()),
970-
).values("scope_id", "title", "org_name", "scope_type")
972+
).values("scope_id", "display_name", "org_name", "scope_type")
971973

972974
self.libraries_qs_patcher = patch.object(
973975
views.AdminConsoleScopesAPIView,
@@ -1179,6 +1181,36 @@ def test_view_permission_filters_libraries_for_non_staff(self):
11791181
external_keys = [item["external_key"] for item in response.data["results"]]
11801182
self.assertIn(self.LIBRARY_ORG1, external_keys)
11811183
self.assertNotIn(self.LIBRARY_ORG2, external_keys)
1184+
# Verify display_name is populated from the library title, not empty.
1185+
for item in response.data["results"]:
1186+
self.assertTrue(item["display_name"])
1187+
1188+
def test_library_display_name_populated_in_standalone_path(self):
1189+
"""display_name is non-empty for libraries when type=library bypasses the union.
1190+
1191+
Regression test: without aliasing learning_package__title as display_name,
1192+
the standalone library queryset returns 'title' as the key and the serializer
1193+
silently produces empty strings since it only reads 'display_name'.
1194+
1195+
Skipped when the stub ContentLibrary model is in use (no learning_package relation).
1196+
"""
1197+
if not hasattr(ContentLibrary, "learning_package"):
1198+
self.skipTest("Stub ContentLibrary has no learning_package relation")
1199+
1200+
user = User.objects.get(username="regular_1")
1201+
self.client.force_authenticate(user=user)
1202+
# Stop both patchers so the real _get_libraries_queryset runs without union.
1203+
self.build_qs_patcher.stop()
1204+
self.libraries_qs_patcher.stop()
1205+
1206+
response = self.client.get(self.url, {"type": "library"})
1207+
1208+
self.libraries_qs_patcher.start()
1209+
self.build_qs_patcher.start()
1210+
self.assertEqual(response.status_code, status.HTTP_200_OK)
1211+
self.assertGreater(response.data["count"], 0)
1212+
for item in response.data["results"]:
1213+
self.assertTrue(item["display_name"])
11821214

11831215
# ------------------------------------------------------------------ #
11841216
# Permission filtering: manage #

0 commit comments

Comments
 (0)