Skip to content

Commit f63e9a1

Browse files
committed
fix: apply feedback related to test and types
1 parent cf192d1 commit f63e9a1

2 files changed

Lines changed: 102 additions & 39 deletions

File tree

cms/djangoapps/contentstore/tests/test_course_listing.py

Lines changed: 88 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
_accessible_courses_iter_for_tests,
2222
_accessible_courses_list_from_groups,
2323
_accessible_courses_summary_iter,
24-
_get_authz_accessible_courses_list,
2524
get_courses_accessible_to_user,
2625
)
2726
from common.djangoapps.course_action_state.models import CourseRerunState
@@ -718,57 +717,118 @@ def test_superuser_gets_all_courses(self):
718717

719718
self.assertEqual(result_ids, expected_ids)
720719

721-
def test_get_authz_accessible_courses_list_with_org_scope(self):
720+
def test_course_listing_with_org_scope(self):
722721
"""
723-
When the scope is an OrgCourseOverviewGlobData, all course keys
724-
returned by `_get_course_keys_for_org_scope` should be included in
725-
the resulting authz keys when the authz toggle is enabled.
722+
Verify that assigning a course role like course_staff with an org-wide scope
723+
(`course-v1:Org1+*`) grants access to all courses in that org when
724+
the AuthZ course authoring toggle is enabled.
726725
"""
727-
authz_keys, _, authz_courses, _ = self._create_courses()
726+
_, _, authz_courses, legacy_courses = self._create_courses()
728727
org_scope = OrgCourseOverviewGlobData(external_key='course-v1:Org1+*')
728+
assign_role_to_user_in_scope(
729+
self.authorized_user.username,
730+
COURSE_STAFF.external_key,
731+
org_scope.external_key,
732+
)
729733

730734
request = self._make_request(self.authorized_user)
731735

732-
with patch(
733-
"cms.djangoapps.contentstore.views.course.get_scopes_for_user_and_permission",
734-
return_value=[org_scope],
735-
), patch(
736-
"cms.djangoapps.contentstore.views.course._get_course_keys_for_org_scope",
737-
return_value=authz_keys,
738-
) as mock_get_keys, patch.object(
736+
with patch.object(
739737
core_toggles.AUTHZ_COURSE_AUTHORING_FLAG,
740738
"is_enabled",
741739
return_value=True,
742740
):
743-
result = _get_authz_accessible_courses_list(request)
741+
courses, _ = get_courses_accessible_to_user(request)
744742

745-
mock_get_keys.assert_called_once_with(org_scope)
746-
self.assertEqual(result, set(authz_keys))
743+
result_ids = {c.id for c in courses}
744+
745+
expected_ids = {
746+
*(c.id for c in authz_courses),
747+
*(c.id for c in legacy_courses),
748+
}
749+
750+
self.assertEqual(result_ids, expected_ids)
747751

748-
def test_get_authz_accessible_courses_list_org_scope_respects_toggle(self):
752+
def test_course_listing_with_org_scope_with_toggle(self):
749753
"""
750754
If the authz toggle is enabled only for a subset of org courses, only
751-
those course keys should appear in the resulting authz keys.
755+
those course keys should appear in the resulting course list.
752756
"""
753-
authz_keys, _, authz_courses, _ = self._create_courses()
757+
authz_keys, _, _, _ = self._create_courses()
754758
# enable only the first and third course keys
755759
enabled_keys = {str(authz_keys[0]), str(authz_keys[2])}
756760
org_scope = OrgCourseOverviewGlobData(external_key='course-v1:Org1+*')
761+
assign_role_to_user_in_scope(
762+
self.authorized_user.username,
763+
COURSE_STAFF.external_key,
764+
org_scope.external_key,
765+
)
757766

758767
request = self._make_request(self.authorized_user)
759768

760-
with patch(
761-
"cms.djangoapps.contentstore.views.course.get_scopes_for_user_and_permission",
762-
return_value=[org_scope],
763-
), patch(
764-
"cms.djangoapps.contentstore.views.course._get_course_keys_for_org_scope",
765-
return_value=authz_keys,
766-
), patch.object(
769+
with patch.object(
767770
core_toggles.AUTHZ_COURSE_AUTHORING_FLAG,
768771
"is_enabled",
769772
side_effect=self._mock_authz_toggle(enabled_keys),
770773
):
771-
result = _get_authz_accessible_courses_list(request)
774+
courses, _ = get_courses_accessible_to_user(request)
775+
776+
result_ids = {c.id for c in courses}
772777

773778
expected = {authz_keys[0], authz_keys[2]}
774-
self.assertEqual(result, expected)
779+
self.assertEqual(result_ids, expected)
780+
781+
def test_course_listing_with_org_scope_without_courses(self):
782+
"""
783+
When the scope is an OrgCourseOverviewGlobData for an org that has no
784+
courses, `get_courses_accessible_to_user` should return an empty
785+
list.
786+
"""
787+
org_scope = OrgCourseOverviewGlobData(external_key='course-v1:Org2+*')
788+
assign_role_to_user_in_scope(
789+
self.authorized_user.username,
790+
COURSE_STAFF.external_key,
791+
org_scope.external_key,
792+
)
793+
794+
request = self._make_request(self.authorized_user)
795+
796+
with patch.object(
797+
core_toggles.AUTHZ_COURSE_AUTHORING_FLAG,
798+
"is_enabled",
799+
return_value=True,
800+
):
801+
courses, _ = get_courses_accessible_to_user(request)
802+
803+
self.assertEqual(courses, [])
804+
805+
def test_course_listing_with_org_scope_fetched_once(self):
806+
"""
807+
Verify that course overviews are fetched once with all authorized orgs.
808+
"""
809+
org_scope1 = OrgCourseOverviewGlobData(external_key='course-v1:Org1+*')
810+
org_scope2 = OrgCourseOverviewGlobData(external_key='course-v1:Org2+*')
811+
assign_role_to_user_in_scope(
812+
self.authorized_user.username,
813+
COURSE_STAFF.external_key,
814+
org_scope1.external_key,
815+
)
816+
assign_role_to_user_in_scope(
817+
self.authorized_user.username,
818+
COURSE_STAFF.external_key,
819+
org_scope2.external_key,
820+
)
821+
822+
request = self._make_request(self.authorized_user)
823+
824+
with patch.object(
825+
core_toggles.AUTHZ_COURSE_AUTHORING_FLAG,
826+
"is_enabled",
827+
return_value=True,
828+
), patch.object(
829+
CourseOverview,
830+
"get_all_courses",
831+
) as mock_get_all_courses:
832+
courses, _ = get_courses_accessible_to_user(request)
833+
834+
mock_get_all_courses.assert_called_once_with(orgs={"Org1", "Org2"})

cms/djangoapps/contentstore/views/course.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -817,12 +817,12 @@ def filter_course(course):
817817
return filter(filter_course, filtered_courses)
818818

819819

820-
def _get_course_keys_for_org_scope(access):
820+
def _get_course_keys_for_org_scope(org_keys: set[str]):
821821
"""
822-
Function to convert an OrgCourseOverviewGlobData scope
823-
into specific course keys.
822+
Convert a set of organization keys into specific course keys.
824823
"""
825-
return CourseOverview.get_all_courses(orgs=[access.org]).values_list('id', flat=True)
824+
825+
return CourseOverview.get_all_courses(orgs=org_keys).values_list('id', flat=True)
826826

827827

828828
def _get_authz_accessible_courses_list(request):
@@ -836,18 +836,21 @@ def _get_authz_accessible_courses_list(request):
836836
COURSES_VIEW_COURSE.identifier
837837
)
838838

839-
authz_keys = set()
839+
course_keys = set()
840+
org_keys = set()
840841
for access in authz_scopes:
841842
if isinstance(access, CourseOverviewData) and access.course_key:
842843
if core_toggles.enable_authz_course_authoring(access.course_key):
843-
authz_keys.add(access.course_key)
844+
course_keys.add(access.course_key)
844845
elif isinstance(access, OrgCourseOverviewGlobData) and access.org:
845-
authz_keys.update(
846-
key for key in _get_course_keys_for_org_scope(access)
847-
if core_toggles.enable_authz_course_authoring(key)
848-
)
846+
org_keys.add(access.org)
847+
if org_keys:
848+
course_keys.update(
849+
key for key in _get_course_keys_for_org_scope(org_keys)
850+
if core_toggles.enable_authz_course_authoring(key)
851+
)
849852

850-
return authz_keys
853+
return course_keys
851854

852855

853856
def _get_legacy_accessible_courses_list(request):

0 commit comments

Comments
 (0)