diff --git a/openedx/core/djangoapps/courseware_api/tests/test_views.py b/openedx/core/djangoapps/courseware_api/tests/test_views.py index af03e6ecd6..0d560fd6cd 100644 --- a/openedx/core/djangoapps/courseware_api/tests/test_views.py +++ b/openedx/core/djangoapps/courseware_api/tests/test_views.py @@ -421,6 +421,11 @@ class SequenceApiTestViews(MasqueradeMixin, BaseCoursewareTests): assert response.data['display_name'] == 'sequence' assert len(response.data['items']) == 1 + def test_unit_error(self): + """Verify that we return a proper error when passed a non-sequence""" + response = self.client.get(f'/api/courseware/sequence/{self.unit.location}') + assert response.status_code == 422 + @ddt.data( (False, None, False, False), (True, None, True, False), diff --git a/openedx/core/djangoapps/courseware_api/views.py b/openedx/core/djangoapps/courseware_api/views.py index d92d134860..a5dc501194 100644 --- a/openedx/core/djangoapps/courseware_api/views.py +++ b/openedx/core/djangoapps/courseware_api/views.py @@ -10,6 +10,7 @@ from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthenticat from edx_rest_framework_extensions.auth.session.authentication import SessionAuthenticationAllowInactiveUser from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey, UsageKey +from rest_framework import status from rest_framework.exceptions import NotFound from rest_framework.generics import RetrieveAPIView from rest_framework.permissions import IsAuthenticated @@ -580,7 +581,8 @@ class SequenceMetadata(DeveloperErrorViewMixin, APIView): * 400 if an invalid parameter was sent. * 403 if a user who does not have permission to masquerade as another user specifies a username other than their own. - * 404 if the course is not available or cannot be seen. + * 404 if the course/usage_key is not available or cannot be seen. + * 422 if the usage key is valid but does not have sequence metadata (like a unit or a problem) """ authentication_classes = ( @@ -611,6 +613,10 @@ class SequenceMetadata(DeveloperErrorViewMixin, APIView): disable_staff_debug_info=True, will_recheck_access=True) + if not hasattr(sequence, 'get_metadata'): + # Looks like we were asked for metadata on something that is not a sequence (or section). + return Response(status=status.HTTP_422_UNPROCESSABLE_ENTITY) + view = STUDENT_VIEW if request.user.is_anonymous: view = PUBLIC_VIEW