fix: jump_to should redirect to first unit on invalid key

Previously, it would 404. While accurate, it's not a great user
experience. Users can be offered invalid jump_to paths in the normal
course of things, if course content disappears or they lose access
to it.

In both cases, they might be offered a resume URL in the courseware
that would be to a now-invalid location.

With this change, that invalid link will at least give them
*something* (the first unit in the course) rather than an error
page.

This also (unrelatedly) fixes an exception when the learning MFE
outline page tries to render a course that contains sequences
with no children.

AA-867
This commit is contained in:
Michael Terry
2021-06-28 14:55:51 -04:00
parent f9082a082e
commit c62626227a
7 changed files with 47 additions and 17 deletions

View File

@@ -427,6 +427,16 @@ class ResumeApiTestViews(BaseCoursewareTests, CompletionWaffleTestMixin):
assert response.data['unit_id'] == str(self.unit.location)
assert response.data['section_id'] == str(self.sequence.location)
def test_resume_invalid_key(self):
"""A resume key that does not exist should return null IDs (i.e. "redirect to first section")"""
self.override_waffle_switch(True)
submit_completions_for_testing(self.user, [self.course.id.make_usage_key('html', 'doesnotexist')])
response = self.client.get(self.url)
assert response.status_code == 200
assert response.data['block_id'] is None
assert response.data['unit_id'] is None
assert response.data['section_id'] is None
@ddt.ddt
class CelebrationApiTestViews(BaseCoursewareTests, MasqueradeMixin):

View File

@@ -2,8 +2,6 @@
Course API Views
"""
import json # lint-amnesty, pylint: disable=unused-import
from completion.exceptions import UnavailableCompletionData
from completion.utilities import get_key_to_last_completed_block
from django.conf import settings
@@ -62,6 +60,7 @@ from common.djangoapps.student.models import (
LinkedInAddToProfileConfiguration
)
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError, NoPathToItem
from xmodule.modulestore.search import path_to_location
from xmodule.x_module import PUBLIC_VIEW, STUDENT_VIEW
@@ -623,8 +622,8 @@ class Resume(DeveloperErrorViewMixin, APIView):
resp['unit_id'] = str(path[3])
resp['block_id'] = str(block_key)
except UnavailableCompletionData:
pass
except (ItemNotFoundError, NoPathToItem, UnavailableCompletionData):
pass # leaving all the IDs as None indicates a redirect to the first unit in the course, as a backup
return Response(resp)