fix: deleted courses do not break program details page
Sometimes learners have certificates in old course runs which've been deleted. When this happens loading the learner's program progress can result in 500 errors. This corrects those by choosing to count any non-existent course the learner has certificates for as counting towards program completion, effectively assuming that availability dates have passed for all such courses. Also fixes an error with a condition related to how we determine whether an enrolled course is considered "in progress". The previous version of the code had a bug that would result in a lot more courses being marked "in progress" for the purpose of program completion than actually were. JIRA:EDUCATOR-5787
This commit is contained in:
committed by
Albert (AJ) St. Aubin
parent
0598cf71d3
commit
8023a09191
@@ -598,7 +598,7 @@ class TestProgramProgressMeter(ModuleStoreTestCase):
|
||||
ProgressFactory(
|
||||
uuid=program_uuid,
|
||||
completed=2,
|
||||
in_progress=1,
|
||||
not_started=1,
|
||||
)
|
||||
)
|
||||
assert list(meter.completed_programs_with_available_dates.keys()) == [program_uuid]
|
||||
@@ -619,6 +619,32 @@ class TestProgramProgressMeter(ModuleStoreTestCase):
|
||||
assert list(meter.completed_programs_with_available_dates.keys()) == [program_uuid]
|
||||
assert meter.completed_programs_with_available_dates[program_uuid].date() == today.date()
|
||||
|
||||
def test_old_course_runs(self, mock_get_programs):
|
||||
"""
|
||||
Test that old course runs may exist for a program which do not exist in LMS.
|
||||
In that case, continue considering the course run to've been failed by the learner
|
||||
"""
|
||||
course_run = CourseRunFactory.create()
|
||||
course = CourseFactory.create(course_runs=[course_run])
|
||||
program_data = ProgramFactory(courses=[course])
|
||||
|
||||
data = [program_data]
|
||||
mock_get_programs.return_value = data
|
||||
|
||||
course_run_key = str(course_run['key'])
|
||||
self._create_enrollments(course_run_key)
|
||||
self._create_certificates(course_run_key, mode=MODES.verified)
|
||||
|
||||
meter = ProgramProgressMeter(self.site, self.user)
|
||||
|
||||
self._assert_progress(
|
||||
meter,
|
||||
ProgressFactory(
|
||||
uuid=program_data['uuid'],
|
||||
not_started=1
|
||||
)
|
||||
)
|
||||
|
||||
def test_nonverified_course_run_completion(self, mock_get_programs):
|
||||
"""
|
||||
Course runs aren't necessarily of type verified. Verify that a program can
|
||||
|
||||
@@ -206,7 +206,7 @@ class ProgramProgressMeter:
|
||||
]
|
||||
|
||||
if runs_with_required_mode:
|
||||
not_failed_runs = [run for run in runs_with_required_mode if run not in self.failed_course_runs]
|
||||
not_failed_runs = [run for run in runs_with_required_mode if run['key'] not in self.failed_course_runs]
|
||||
if not_failed_runs:
|
||||
return True
|
||||
|
||||
@@ -417,7 +417,7 @@ class ProgramProgressMeter:
|
||||
Determine which course runs have been failed by the user.
|
||||
|
||||
Returns:
|
||||
list of dicts, each a course run ID
|
||||
list of strings, each a course run ID
|
||||
"""
|
||||
return [run['course_run_id'] for run in self.course_runs_with_state['failed']]
|
||||
|
||||
@@ -442,9 +442,13 @@ class ProgramProgressMeter:
|
||||
'type': self._certificate_mode_translation(certificate['type']),
|
||||
}
|
||||
|
||||
try:
|
||||
may_certify = CourseOverview.get_from_id(course_key).may_certify()
|
||||
except CourseOverview.DoesNotExist:
|
||||
may_certify = True
|
||||
if (
|
||||
certificate_api.is_passing_status(certificate['status'])
|
||||
and CourseOverview.get_from_id(course_key).may_certify()
|
||||
and may_certify
|
||||
):
|
||||
completed_runs.append(course_data)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user