diff --git a/lms/djangoapps/course_home_api/outline/tests/test_view.py b/lms/djangoapps/course_home_api/outline/tests/test_view.py index e9a3570ea6bd..acfe86ca8ed8 100644 --- a/lms/djangoapps/course_home_api/outline/tests/test_view.py +++ b/lms/djangoapps/course_home_api/outline/tests/test_view.py @@ -10,6 +10,7 @@ import ddt from completion.models import BlockCompletion from django.conf import settings +from django.contrib.auth.models import AnonymousUser from django.test import override_settings from django.urls import reverse from edx_toggles.toggles.testutils import override_waffle_flag @@ -20,6 +21,7 @@ from common.djangoapps.student.models import CourseEnrollment from common.djangoapps.student.roles import CourseInstructorRole from common.djangoapps.student.tests.factories import UserFactory +from lms.djangoapps.course_home_api.outline.views import CourseNavigationBlocksView from lms.djangoapps.course_home_api.tests.utils import BaseCourseHomeTests from lms.djangoapps.course_home_api.toggles import COURSE_HOME_SEND_COURSE_PROGRESS_ANALYTICS_FOR_STUDENT from lms.djangoapps.grades.course_grade_factory import CourseGradeFactory @@ -584,6 +586,20 @@ def test_get_unauthenticated_user(self): assert response.status_code == 200 assert response.data.get('blocks') is None + def test_anonymous_user_completion_dict_does_not_lookup_completions(self): + """ + Test that anonymous users do not query completion data. + """ + view = CourseNavigationBlocksView() + view.request = Mock(user=AnonymousUser()) + view.kwargs = {'course_key_string': str(self.course.id)} + + with patch('lms.djangoapps.course_home_api.outline.views.BlockCompletion.objects.filter') as mock_filter: + completions = view.completions_dict + + assert completions == {} + mock_filter.assert_not_called() + def test_course_staff_can_see_non_user_specific_content_in_masquerade(self): """ Test that course staff can see the outline and other non-user-specific content when masquerading as a learner diff --git a/lms/djangoapps/course_home_api/outline/views.py b/lms/djangoapps/course_home_api/outline/views.py index 0c62d8a34921..b9168c6ca5fa 100644 --- a/lms/djangoapps/course_home_api/outline/views.py +++ b/lms/djangoapps/course_home_api/outline/views.py @@ -613,6 +613,11 @@ def completions_dict(self): Dictionary keys are block keys and values are int values representing the completion status of the block. """ + # Anonymous users have no completion rows; return empty data to avoid + # querying BlockCompletion with AnonymousUser for public course navigation. + if self.request.user.is_anonymous: + return {} + course_key_string = self.kwargs.get('course_key_string') course_key = CourseKey.from_string(course_key_string) completions = BlockCompletion.objects.filter(user=self.request.user, context_key=course_key).values_list(