1414 OrgContentLibraryGlobData ,
1515 OrgCourseOverviewGlobData ,
1616 PermissionData ,
17+ PlatformContentLibraryGlobData ,
1718 PlatformCourseOverviewGlobData ,
1819 RoleAssignmentData ,
1920 RoleData ,
@@ -271,12 +272,15 @@ def test_scope_data_registration(self):
271272 # Glob registries for platform-level scopes
272273 self .assertIn ("course-v1" , ScopeMeta .platform_glob_registry )
273274 self .assertIs (ScopeMeta .platform_glob_registry ["course-v1" ], PlatformCourseOverviewGlobData )
275+ self .assertIn ("lib" , ScopeMeta .platform_glob_registry )
276+ self .assertIs (ScopeMeta .platform_glob_registry ["lib" ], PlatformContentLibraryGlobData )
274277
275278 @data (
276279 ("ccx-v1^ccx-v1:OpenedX+DemoX+DemoCourse+ccx@1" , CCXCourseOverviewData ),
277280 ("course-v1^course-v1:WGU+CS002+2025_T1" , CourseOverviewData ),
278281 ("lib^lib:DemoX:CSPROB" , ContentLibraryData ),
279282 ("lib^lib:DemoX*" , OrgContentLibraryGlobData ),
283+ ("lib^lib:*" , PlatformContentLibraryGlobData ),
280284 ("course-v1^course-v1:OpenedX*" , OrgCourseOverviewGlobData ),
281285 ("course-v1^course-v1:*" , PlatformCourseOverviewGlobData ),
282286 ("global^generic_scope" , ScopeData ),
@@ -299,6 +303,7 @@ def test_dynamic_instantiation_via_namespaced_key(self, namespaced_key, expected
299303 ("course-v1^course-v1:WGU+CS002+2025_T1" , CourseOverviewData ),
300304 ("lib^lib:DemoX:CSPROB" , ContentLibraryData ),
301305 ("lib^lib:DemoX:*" , OrgContentLibraryGlobData ),
306+ ("lib^lib:*" , PlatformContentLibraryGlobData ),
302307 ("course-v1^course-v1:OpenedX+*" , OrgCourseOverviewGlobData ),
303308 ("course-v1^course-v1:*" , PlatformCourseOverviewGlobData ),
304309 ("lib^*" , ScopeData ),
@@ -458,6 +463,7 @@ def test_get_subclass_by_namespaced_key_invalid_glob_pattern_raises(self, namesp
458463 ("course-v1:WGU+CS002+2025_T1" , CourseOverviewData ),
459464 ("lib:DemoX:CSPROB" , ContentLibraryData ),
460465 ("lib:DemoX:*" , OrgContentLibraryGlobData ),
466+ ("lib:*" , PlatformContentLibraryGlobData ),
461467 ("course-v1:OpenedX+*" , OrgCourseOverviewGlobData ),
462468 ("course-v1:*" , PlatformCourseOverviewGlobData ),
463469 ("lib:edX:Demo" , ContentLibraryData ),
@@ -537,8 +543,11 @@ def test_is_platform_glob(self, namespace, external_key, expected):
537543 def test_platform_glob_registration_does_not_override_scope_registry (self ):
538544 """Platform globs register separately; concrete scopes keep scope_registry entries."""
539545 self .assertIs (ScopeData .scope_registry ["course-v1" ], CourseOverviewData )
546+ self .assertIs (ScopeData .scope_registry ["lib" ], ContentLibraryData )
540547 self .assertIs (ScopeMeta .platform_glob_registry ["course-v1" ], PlatformCourseOverviewGlobData )
548+ self .assertIs (ScopeMeta .platform_glob_registry ["lib" ], PlatformContentLibraryGlobData )
541549 self .assertNotIn (PlatformCourseOverviewGlobData , ScopeData .scope_registry .values ())
550+ self .assertNotIn (PlatformContentLibraryGlobData , ScopeData .scope_registry .values ())
542551
543552 def test_platform_glob_resolves_before_org_glob_for_course_namespace (self ):
544553 """course-v1:* is a platform glob; course-v1:Org+* remains an org glob."""
@@ -557,16 +566,32 @@ def test_dynamic_instantiation_via_external_key_for_platform_glob(self):
557566 self .assertEqual (scope .external_key , "course-v1:*" )
558567 self .assertEqual (scope .namespaced_key , "course-v1^course-v1:*" )
559568
569+ def test_platform_glob_resolves_before_org_glob_for_lib_namespace (self ):
570+ """lib:* is a platform glob; lib:Org:* remains an org glob."""
571+ self .assertIs (ScopeMeta .get_subclass_by_external_key ("lib:*" ), PlatformContentLibraryGlobData )
572+ self .assertIs (ScopeMeta .get_subclass_by_external_key ("lib:DemoX:*" ), OrgContentLibraryGlobData )
573+ self .assertIs (ScopeMeta .get_subclass_by_namespaced_key ("lib^lib:*" ), PlatformContentLibraryGlobData )
574+ self .assertIs (ScopeMeta .get_subclass_by_namespaced_key ("lib^lib:DemoX:*" ), OrgContentLibraryGlobData )
575+
576+ def test_dynamic_instantiation_via_external_key_for_lib_platform_glob (self ):
577+ """ScopeData(external_key='lib:*') instantiates PlatformContentLibraryGlobData."""
578+ scope = ScopeData (external_key = "lib:*" )
579+
580+ self .assertIsInstance (scope , PlatformContentLibraryGlobData )
581+ self .assertEqual (scope .external_key , "lib:*" )
582+ self .assertEqual (scope .namespaced_key , "lib^lib:*" )
583+
560584 def test_get_subclass_by_external_key_unknown_platform_glob_raises_value_error (self ):
561585 """Namespace:* without a registered platform glob subclass raises ValueError."""
562586 with self .assertRaisesRegex (ValueError , "Unknown platform glob scope" ):
563- ScopeMeta .get_subclass_by_external_key ("lib :*" )
587+ ScopeMeta .get_subclass_by_external_key ("ccx-v1 :*" )
564588
565589 def test_get_all_registered_scopes_includes_platform_glob (self ):
566590 """get_all_registered_scopes returns platform glob subclasses."""
567591 registered = ScopeMeta .get_all_registered_scopes ()
568592
569593 self .assertIn (PlatformCourseOverviewGlobData , registered )
594+ self .assertIn (PlatformContentLibraryGlobData , registered )
570595 self .assertIn (OrgCourseOverviewGlobData , registered )
571596 self .assertIn (CourseOverviewData , registered )
572597
@@ -1157,3 +1182,77 @@ def test_get_all_platform_glob_namespaces(self):
11571182
11581183 self .assertIn ("course-v1" , platform_globs )
11591184 self .assertIs (platform_globs ["course-v1" ], PlatformCourseOverviewGlobData )
1185+
1186+
1187+ @ddt
1188+ class TestPlatformContentLibraryGlobData (TestCase ):
1189+ """Tests for the PlatformContentLibraryGlobData scope."""
1190+
1191+ PLATFORM_GLOB_EXTERNAL_KEY = "lib:*"
1192+ PLATFORM_GLOB_NAMESPACED_KEY = "lib^lib:*"
1193+
1194+ def test_build_external_key (self ):
1195+ """build_external_key returns the platform-wide library glob pattern."""
1196+ self .assertEqual (PlatformContentLibraryGlobData .build_external_key (), self .PLATFORM_GLOB_EXTERNAL_KEY )
1197+
1198+ @data (
1199+ ("lib:*" , True ),
1200+ ("lib:DemoX:*" , False ),
1201+ ("lib:DemoX*" , False ),
1202+ ("lib:DemoX" , False ),
1203+ ("lib:*:*" , False ),
1204+ ("other:*" , False ),
1205+ ("course-v1:*" , False ),
1206+ )
1207+ @unpack
1208+ def test_validate_external_key (self , external_key , expected_valid ):
1209+ """Validate platform-level library glob external keys."""
1210+ self .assertEqual (PlatformContentLibraryGlobData .validate_external_key (external_key ), expected_valid )
1211+
1212+ def test_exists_always_true (self ):
1213+ """exists() returns True without checking the database."""
1214+ scope = PlatformContentLibraryGlobData (external_key = self .PLATFORM_GLOB_EXTERNAL_KEY )
1215+
1216+ self .assertTrue (scope .exists ())
1217+
1218+ def test_get_object_returns_none (self ):
1219+ """Platform glob scopes do not map to a concrete domain object."""
1220+ scope = PlatformContentLibraryGlobData (external_key = self .PLATFORM_GLOB_EXTERNAL_KEY )
1221+
1222+ self .assertIsNone (scope .get_object ())
1223+
1224+ def test_namespaced_key (self ):
1225+ """namespaced_key includes namespace prefix and external key."""
1226+ scope = PlatformContentLibraryGlobData (external_key = self .PLATFORM_GLOB_EXTERNAL_KEY )
1227+
1228+ self .assertEqual (scope .namespaced_key , self .PLATFORM_GLOB_NAMESPACED_KEY )
1229+
1230+ def test_dynamic_instantiation_via_scope_data (self ):
1231+ """ScopeData resolves lib:* to PlatformContentLibraryGlobData."""
1232+ scope = ScopeData (external_key = self .PLATFORM_GLOB_EXTERNAL_KEY )
1233+
1234+ self .assertIsInstance (scope , PlatformContentLibraryGlobData )
1235+ self .assertEqual (scope .external_key , self .PLATFORM_GLOB_EXTERNAL_KEY )
1236+
1237+ def test_get_admin_view_permission (self ):
1238+ """View permission matches library team view permission."""
1239+ self .assertEqual (PlatformContentLibraryGlobData .get_admin_view_permission (), permissions .VIEW_LIBRARY_TEAM )
1240+
1241+ def test_get_admin_manage_permission (self ):
1242+ """Manage permission matches library team manage permission."""
1243+ self .assertEqual (
1244+ PlatformContentLibraryGlobData .get_admin_manage_permission (),
1245+ permissions .MANAGE_LIBRARY_TEAM ,
1246+ )
1247+
1248+ def test_is_platform_glob (self ):
1249+ """Platform library glob is flagged as a platform-level glob scope."""
1250+ self .assertTrue (PlatformContentLibraryGlobData .IS_PLATFORM_GLOB )
1251+ self .assertFalse (PlatformContentLibraryGlobData .IS_ORG_GLOB )
1252+
1253+ def test_get_all_platform_glob_namespaces (self ):
1254+ """Platform glob namespace is registered in ScopeMeta."""
1255+ platform_globs = ScopeMeta .get_all_platform_glob_namespaces ()
1256+
1257+ self .assertIn ("lib" , platform_globs )
1258+ self .assertIs (platform_globs ["lib" ], PlatformContentLibraryGlobData )
0 commit comments