diff --git a/openedx/core/djangoapps/programs/tests/test_utils.py b/openedx/core/djangoapps/programs/tests/test_utils.py index b61fdfe5ea..c6f9125125 100644 --- a/openedx/core/djangoapps/programs/tests/test_utils.py +++ b/openedx/core/djangoapps/programs/tests/test_utils.py @@ -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 diff --git a/openedx/core/djangoapps/programs/utils.py b/openedx/core/djangoapps/programs/utils.py index 5b34d97330..62ac9fb314 100644 --- a/openedx/core/djangoapps/programs/utils.py +++ b/openedx/core/djangoapps/programs/utils.py @@ -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: