@@ -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